@kosdev-code/kos-dispense-sdk 2.1.38 → 2.1.39

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 (38) hide show
  1. package/dispense-registration-manager-C6k10ipu.cjs +2698 -0
  2. package/dispense-registration-manager-C6k10ipu.cjs.map +1 -0
  3. package/dispense-registration-manager-lJlcyq5G.js +2700 -0
  4. package/dispense-registration-manager-lJlcyq5G.js.map +1 -0
  5. package/{extension-utils-DrsPfQWC.js → extension-utils-AS0Z5eod.js} +194 -157
  6. package/{extension-utils-DrsPfQWC.js.map → extension-utils-AS0Z5eod.js.map} +1 -1
  7. package/extension-utils-DNbm2KRk.cjs +500 -0
  8. package/{extension-utils-BDyaRwRN.cjs.map → extension-utils-DNbm2KRk.cjs.map} +1 -1
  9. package/index.cjs +142 -1
  10. package/index.cjs.map +1 -1
  11. package/index.js +124 -121
  12. package/index.js.map +1 -1
  13. package/kos-models.json +1 -1
  14. package/models/models/assembly/holder-utils.d.ts.map +1 -1
  15. package/models/models/holder/holder-model.d.ts.map +1 -1
  16. package/models/models/holder/types/index.d.ts +2 -0
  17. package/models/models/nozzle/nozzle-model.d.ts +1 -0
  18. package/models/models/nozzle/nozzle-model.d.ts.map +1 -1
  19. package/models/models/types/assembly.d.ts +1 -0
  20. package/models/models/types/assembly.d.ts.map +1 -1
  21. package/models.cjs +47 -1
  22. package/models.cjs.map +1 -1
  23. package/models.js +40 -40
  24. package/package.json +14 -2
  25. package/pump-provider-BSEusYig.js +1825 -0
  26. package/{pump-provider-Bytd6qXc.js.map → pump-provider-BSEusYig.js.map} +1 -1
  27. package/pump-provider-D4Ed_gH6.cjs +1824 -0
  28. package/{pump-provider-CTELJBW5.cjs.map → pump-provider-D4Ed_gH6.cjs.map} +1 -1
  29. package/ui.cjs +73 -1
  30. package/ui.cjs.map +1 -1
  31. package/ui.js +67 -67
  32. package/dispense-registration-manager-Cj0565Ze.cjs +0 -2
  33. package/dispense-registration-manager-Cj0565Ze.cjs.map +0 -1
  34. package/dispense-registration-manager-CzAqcL8D.js +0 -2044
  35. package/dispense-registration-manager-CzAqcL8D.js.map +0 -1
  36. package/extension-utils-BDyaRwRN.cjs +0 -2
  37. package/pump-provider-Bytd6qXc.js +0 -1308
  38. package/pump-provider-CTELJBW5.cjs +0 -2
@@ -0,0 +1,1824 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
8
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
9
+ const kosUiSdk = require("@kosdev-code/kos-ui-sdk");
10
+ const dispenseRegistrationManager = require("./dispense-registration-manager-C6k10ipu.cjs");
11
+ const React = require("react");
12
+ const useAssembly = () => {
13
+ const modelId = dispenseRegistrationManager.Assembly.type;
14
+ const result = kosUiSdk.useKosModel({
15
+ modelId,
16
+ modelType: dispenseRegistrationManager.Assembly.type,
17
+ options: {}
18
+ });
19
+ return result;
20
+ };
21
+ function withAssembly(WrappedComponent) {
22
+ return (props) => {
23
+ const { model, status, KosModelLoader } = useAssembly();
24
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, assembly: model }) });
25
+ };
26
+ }
27
+ const useAvailability = () => {
28
+ const modelId = dispenseRegistrationManager.Availability.type;
29
+ const result = kosUiSdk.useKosModel({
30
+ modelId,
31
+ modelType: dispenseRegistrationManager.Availability.type,
32
+ options: {}
33
+ });
34
+ return result;
35
+ };
36
+ function withBeverage(WrappedComponent) {
37
+ return (props) => {
38
+ const { model, status, KosModelLoader } = useAvailability();
39
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, beverage: model }) });
40
+ };
41
+ }
42
+ const useBoard = (id) => {
43
+ const modelId = id;
44
+ const result = kosUiSdk.useKosModel({
45
+ modelId,
46
+ modelType: dispenseRegistrationManager.Board.type,
47
+ options: {}
48
+ });
49
+ return result;
50
+ };
51
+ function withBoard(WrappedComponent) {
52
+ return (id) => (props) => {
53
+ const { model, status, KosModelLoader } = useBoard(id);
54
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, board: model }) });
55
+ };
56
+ }
57
+ const useBoardContainer = () => {
58
+ const modelId = dispenseRegistrationManager.BoardContainer.type;
59
+ const result = kosUiSdk.useKosModel({
60
+ modelId,
61
+ modelType: dispenseRegistrationManager.BoardContainer.type,
62
+ options: {}
63
+ });
64
+ return result;
65
+ };
66
+ function withBoardContainer(WrappedComponent) {
67
+ return (props) => {
68
+ const { model, status, KosModelLoader } = useBoardContainer();
69
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, boardContainer: model }) });
70
+ };
71
+ }
72
+ const useNozzle = (path) => {
73
+ const modelId = path;
74
+ const result = kosUiSdk.useKosModel({
75
+ modelId,
76
+ modelType: dispenseRegistrationManager.Nozzle.type,
77
+ options: {
78
+ path
79
+ }
80
+ });
81
+ return result;
82
+ };
83
+ const Nozzle = React.createContext(void 0);
84
+ const NozzleProvider = ({ children, path }) => {
85
+ const { model, ready } = useNozzle(path);
86
+ const value = React.useMemo(() => {
87
+ if (ready && model) {
88
+ return { model };
89
+ }
90
+ return {};
91
+ }, [ready, model]);
92
+ return /* @__PURE__ */ jsxRuntime.jsx(Nozzle.Provider, { value, children });
93
+ };
94
+ const useNozzleContext = () => {
95
+ const context = React.useContext(Nozzle);
96
+ if (!context) {
97
+ throw new Error("useNozzleContext must be used within a NozzleProvider");
98
+ }
99
+ return context;
100
+ };
101
+ const useBeverages = ({
102
+ onBeverageSelected,
103
+ onBeverageListUpdated,
104
+ onClearBeverage,
105
+ companionType
106
+ }) => {
107
+ const { model: nozzle } = useNozzleContext();
108
+ const [beverages, setBeverages] = React.useState([]);
109
+ const [selectedBeverage, setSelectedBeverage] = React.useState(null);
110
+ const companions = React.useMemo(() => {
111
+ if (!companionType)
112
+ return [];
113
+ return beverages.map(
114
+ (brand) => kosUiSdk.getKosCompanionModel(brand, companionType)
115
+ );
116
+ }, [beverages, companionType]);
117
+ const selectBeverage = React.useCallback(
118
+ async (beverage, context, forceUpdate) => {
119
+ setSelectedBeverage(beverage);
120
+ await (nozzle == null ? void 0 : nozzle.setSelectedPourable({ beverage, context }, forceUpdate));
121
+ onBeverageSelected == null ? void 0 : onBeverageSelected(beverage);
122
+ },
123
+ [nozzle, onBeverageSelected]
124
+ );
125
+ const clearBeverage = React.useCallback(async () => {
126
+ setSelectedBeverage(null);
127
+ await (nozzle == null ? void 0 : nozzle.setSelectedPourable({ beverage: void 0 }));
128
+ onClearBeverage == null ? void 0 : onClearBeverage();
129
+ }, [nozzle, onClearBeverage]);
130
+ React.useEffect(() => {
131
+ const disposer = kosUiSdk.kosAutoEffect(() => {
132
+ if (!nozzle)
133
+ return;
134
+ const selectedBrand = nozzle.selectedBrand;
135
+ if (!selectedBrand) {
136
+ const allBeverages = nozzle.getGroupAvailabilityItems("beverages").filter((beverage) => beverage.visible);
137
+ setBeverages(allBeverages ?? []);
138
+ onBeverageListUpdated == null ? void 0 : onBeverageListUpdated(allBeverages);
139
+ return;
140
+ }
141
+ const beverages2 = nozzle.getAvailabilityByParent(selectedBrand.id).filter((b) => b.visible);
142
+ setBeverages(beverages2 ?? []);
143
+ onBeverageListUpdated == null ? void 0 : onBeverageListUpdated(beverages2);
144
+ });
145
+ return () => {
146
+ disposer();
147
+ };
148
+ }, [nozzle]);
149
+ return {
150
+ beverages,
151
+ beverageCompanions: companions,
152
+ selectBeverage,
153
+ selectedBeverage,
154
+ clearBeverage
155
+ };
156
+ };
157
+ const useBrands = ({
158
+ onBrandSelected,
159
+ onBrandCleared,
160
+ companionType
161
+ }) => {
162
+ const { model: nozzle } = useNozzleContext();
163
+ const [selectedBrand, setSelectedBrand] = React.useState(null);
164
+ const [brands, setBrands] = React.useState([]);
165
+ const companions = React.useMemo(() => {
166
+ if (!companionType)
167
+ return [];
168
+ return brands.map((brand) => kosUiSdk.getKosCompanionModel(brand, companionType));
169
+ }, [brands, companionType]);
170
+ const selectBrand = React.useCallback(
171
+ async (brand, context, forceUpdate) => {
172
+ setSelectedBrand(brand);
173
+ if (forceUpdate) {
174
+ kosUiSdk.KosLog.warn(
175
+ `forceUpdate is not currently supported when setting brand`
176
+ );
177
+ }
178
+ nozzle == null ? void 0 : nozzle.setSelectedBrand(brand, context);
179
+ onBrandSelected == null ? void 0 : onBrandSelected(brand);
180
+ },
181
+ [nozzle, onBrandSelected]
182
+ );
183
+ const clearBrand = React.useCallback(() => {
184
+ setSelectedBrand(null);
185
+ nozzle == null ? void 0 : nozzle.setSelectedBrand(void 0);
186
+ onBrandCleared == null ? void 0 : onBrandCleared();
187
+ }, [nozzle, onBrandCleared]);
188
+ React.useEffect(() => {
189
+ const disposer = kosUiSdk.kosAutoEffect(() => {
190
+ if (!nozzle)
191
+ return;
192
+ setBrands(nozzle.visibleBrands);
193
+ });
194
+ return () => {
195
+ disposer();
196
+ };
197
+ }, [nozzle]);
198
+ return {
199
+ brands,
200
+ brandCompanions: companions,
201
+ selectedBrand,
202
+ selectBrand,
203
+ clearBrand
204
+ };
205
+ };
206
+ class PourContext {
207
+ constructor() {
208
+ __publicField(this, "_data", /* @__PURE__ */ new Map());
209
+ }
210
+ get(key) {
211
+ return this._data.get(key);
212
+ }
213
+ set(key, value) {
214
+ this._data.set(key, value);
215
+ }
216
+ remove(key) {
217
+ this._data.delete(key);
218
+ }
219
+ has(key) {
220
+ return this._data.has(key);
221
+ }
222
+ }
223
+ const logger$7 = kosUiSdk.KosLog.createLogger({
224
+ name: "HoldToPourStrategy",
225
+ group: "kos-hooks"
226
+ });
227
+ const HoldToPourStrategy = {
228
+ name: "HoldToPourStrategy",
229
+ async initiate(nozzle) {
230
+ if (!(nozzle == null ? void 0 : nozzle.canPour)) {
231
+ logger$7.debug(`Nozzle ${nozzle == null ? void 0 : nozzle.id} cannot pour. Returning early.`);
232
+ return;
233
+ }
234
+ await (nozzle == null ? void 0 : nozzle.pour());
235
+ },
236
+ async initiateEnded(nozzle) {
237
+ await (nozzle == null ? void 0 : nozzle.cancelPour());
238
+ }
239
+ };
240
+ const logger$6 = kosUiSdk.KosLog.createLogger({
241
+ name: "useNozzlePour",
242
+ group: "kos-hooks"
243
+ });
244
+ const useNozzlePour = ({
245
+ onPour,
246
+ onPourCancel,
247
+ onBeforePour,
248
+ onBeforePourRejected,
249
+ pourContext,
250
+ strategy = HoldToPourStrategy
251
+ }) => {
252
+ const { model: nozzle } = useNozzleContext();
253
+ const [context, _setContext] = React.useState(
254
+ pourContext || new PourContext()
255
+ );
256
+ const handlePour = React.useCallback(async () => {
257
+ const canPour = onBeforePour ? await (onBeforePour == null ? void 0 : onBeforePour(context)) : true;
258
+ if (canPour) {
259
+ logger$6.debug(
260
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiated for nozzle ${nozzle == null ? void 0 : nozzle.id}.`
261
+ );
262
+ strategy == null ? void 0 : strategy.initiate(nozzle);
263
+ onPour == null ? void 0 : onPour();
264
+ } else {
265
+ logger$6.debug(
266
+ `[${strategy == null ? void 0 : strategy.name}] - Did not pass onBeforePour gate for nozzle ${nozzle == null ? void 0 : nozzle.id}. Cancelling pour.`
267
+ );
268
+ onBeforePourRejected == null ? void 0 : onBeforePourRejected();
269
+ }
270
+ }, [
271
+ onPour,
272
+ nozzle,
273
+ strategy,
274
+ onBeforePour,
275
+ onPourCancel,
276
+ context,
277
+ onBeforePourRejected
278
+ ]);
279
+ const handleCancelPour = React.useCallback(() => {
280
+ var _a;
281
+ logger$6.debug(
282
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiate ended called for nozzle ${nozzle == null ? void 0 : nozzle.id}.`
283
+ );
284
+ (_a = strategy == null ? void 0 : strategy.initiateEnded) == null ? void 0 : _a.call(strategy, nozzle);
285
+ onPourCancel == null ? void 0 : onPourCancel();
286
+ }, [onPourCancel, nozzle, strategy]);
287
+ const forceCancelPour = React.useCallback(() => {
288
+ logger$6.debug(`Force cancelling pour for nozzle ${nozzle == null ? void 0 : nozzle.id}.`);
289
+ nozzle == null ? void 0 : nozzle.cancelPour();
290
+ onPourCancel == null ? void 0 : onPourCancel();
291
+ }, [onPourCancel, nozzle]);
292
+ const handleUpdateContext = React.useCallback(
293
+ (key, value) => {
294
+ context.set(key, value);
295
+ },
296
+ [context]
297
+ );
298
+ const handleRemoveFromContext = React.useCallback(
299
+ (key) => {
300
+ context.remove(key);
301
+ },
302
+ [context]
303
+ );
304
+ const handlers = kosUiSdk.usePressGesture({
305
+ onPressed: handlePour,
306
+ onRelease: handleCancelPour
307
+ });
308
+ return {
309
+ handlers: handlers.dom,
310
+ cancel: forceCancelPour,
311
+ updatePourContext: handleUpdateContext,
312
+ removeFromPourContext: handleRemoveFromContext,
313
+ status: nozzle
314
+ };
315
+ };
316
+ const useFlavors = ({
317
+ onFlavorSelected,
318
+ onFlavorCleared,
319
+ companionType
320
+ }) => {
321
+ const { model: nozzle } = useNozzleContext();
322
+ const flavors = React.useMemo(
323
+ () => (nozzle == null ? void 0 : nozzle.getGroupAvailabilityItems("flavors").filter((f) => f.visible)) ?? [],
324
+ [nozzle]
325
+ );
326
+ const companions = React.useMemo(() => {
327
+ if (!companionType)
328
+ return [];
329
+ return flavors.map(
330
+ (flavor) => kosUiSdk.getKosCompanionModel(flavor, companionType)
331
+ );
332
+ }, [flavors, companionType]);
333
+ const [selectedFlavors, setSelectedFlavors] = React.useState([]);
334
+ const selectFlavor = React.useCallback(
335
+ async (flavor, context, forceUpdate) => {
336
+ setSelectedFlavors(
337
+ (previous) => (previous == null ? void 0 : previous.includes(flavor)) ? [...previous.filter((p) => p !== flavor)] : [...previous ?? [], flavor]
338
+ );
339
+ if (nozzle == null ? void 0 : nozzle.selectedPourable) {
340
+ const { beverage } = nozzle.selectedPourable;
341
+ await nozzle.setSelectedPourable(
342
+ {
343
+ beverage,
344
+ additional: selectedFlavors ?? [],
345
+ context
346
+ },
347
+ forceUpdate
348
+ );
349
+ }
350
+ onFlavorSelected == null ? void 0 : onFlavorSelected(flavor, selectedFlavors ?? []);
351
+ },
352
+ [nozzle, onFlavorSelected, selectedFlavors]
353
+ );
354
+ const clear = React.useCallback(async () => {
355
+ setSelectedFlavors([]);
356
+ if (nozzle == null ? void 0 : nozzle.selectedPourable) {
357
+ const { beverage } = nozzle.selectedPourable;
358
+ nozzle.setSelectedPourable({ beverage });
359
+ onFlavorCleared == null ? void 0 : onFlavorCleared();
360
+ }
361
+ }, [nozzle, onFlavorCleared]);
362
+ return {
363
+ flavors,
364
+ flavorCompanions: companions,
365
+ selectFlavor,
366
+ selectedFlavors,
367
+ clearFlavors: clear
368
+ };
369
+ };
370
+ const DISPENSE_GROUP_BRAND = "brands";
371
+ const DISPENSE_GROUP_BEVERAGE = "beverages";
372
+ const DISPENSE_GROUP_FLAVOR = "flavors";
373
+ const log$2 = kosUiSdk.KosLog.createLogger({ name: "use-cui-kit" });
374
+ const useCuiKit = ({
375
+ initialGroup = DISPENSE_GROUP_BRAND,
376
+ options = {}
377
+ }) => {
378
+ var _a, _b, _c;
379
+ const [currentGroup, setCurrentGroup] = React.useState(initialGroup);
380
+ const { model: nozzle } = useNozzleContext();
381
+ const timersRef = React.useRef([]);
382
+ const updatePourContext = React.useRef();
383
+ const removeFromPourContext = React.useRef();
384
+ const onBrandSelected = React.useCallback(
385
+ (model) => {
386
+ setCurrentGroup(DISPENSE_GROUP_BEVERAGE);
387
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/brand/selected/`;
388
+ kosUiSdk.EventBus.publish(topic, model);
389
+ },
390
+ [nozzle == null ? void 0 : nozzle.path]
391
+ );
392
+ const onBrandCleared = React.useCallback(() => {
393
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/brand/cleared/`;
394
+ kosUiSdk.EventBus.publish(topic, {});
395
+ }, [nozzle == null ? void 0 : nozzle.path]);
396
+ const onBeverageListUpdated = React.useCallback(
397
+ (beverages2) => {
398
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/beverage/list/updated/`;
399
+ kosUiSdk.EventBus.publish(topic, beverages2);
400
+ },
401
+ [nozzle == null ? void 0 : nozzle.path]
402
+ );
403
+ const onBeverageSelected = React.useCallback(
404
+ (model) => {
405
+ var _a2;
406
+ setCurrentGroup(DISPENSE_GROUP_FLAVOR);
407
+ (_a2 = updatePourContext.current) == null ? void 0 : _a2.call(updatePourContext, "selectedBeverage", model);
408
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/beverage/selected/`;
409
+ kosUiSdk.EventBus.publish(topic, model);
410
+ },
411
+ [nozzle == null ? void 0 : nozzle.path]
412
+ );
413
+ const onBeverageCleared = React.useCallback(() => {
414
+ var _a2;
415
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/beverage/cleared/`;
416
+ (_a2 = removeFromPourContext.current) == null ? void 0 : _a2.call(removeFromPourContext, "selectedBeverage");
417
+ kosUiSdk.EventBus.publish(topic, {});
418
+ }, [nozzle == null ? void 0 : nozzle.path]);
419
+ const onFlavorSelected = React.useCallback(
420
+ (model) => {
421
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/flavor/selected/`;
422
+ kosUiSdk.EventBus.publish(topic, model);
423
+ },
424
+ [nozzle == null ? void 0 : nozzle.path]
425
+ );
426
+ const onFlavorCleared = React.useCallback(() => {
427
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/flavor/cleared/`;
428
+ kosUiSdk.EventBus.publish(topic, {});
429
+ }, [nozzle == null ? void 0 : nozzle.path]);
430
+ const onPour = React.useCallback(() => {
431
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/pour/`;
432
+ kosUiSdk.EventBus.publish(topic, {});
433
+ }, [nozzle == null ? void 0 : nozzle.path]);
434
+ const handleBeforePour = React.useCallback(
435
+ async (context) => {
436
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/pre/pour/`;
437
+ kosUiSdk.EventBus.publish(topic, {});
438
+ return await (onBeforePour == null ? void 0 : onBeforePour(context)) || true;
439
+ },
440
+ [nozzle == null ? void 0 : nozzle.path]
441
+ );
442
+ const handleBeforePourRejected = React.useCallback(async () => {
443
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/pre/pour/rejected/`;
444
+ kosUiSdk.EventBus.publish(topic, {});
445
+ }, [nozzle == null ? void 0 : nozzle.path]);
446
+ const onPourCancel = React.useCallback(() => {
447
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/pour/cancel/`;
448
+ kosUiSdk.EventBus.publish(topic, {});
449
+ }, [nozzle == null ? void 0 : nozzle.path]);
450
+ const { brands, selectBrand, selectedBrand, clearBrand, brandCompanions } = useBrands({
451
+ companionType: (_a = options.companionTypes) == null ? void 0 : _a.brand,
452
+ onBrandSelected,
453
+ onBrandCleared
454
+ });
455
+ const {
456
+ beverages,
457
+ selectBeverage,
458
+ selectedBeverage,
459
+ clearBeverage,
460
+ beverageCompanions
461
+ } = useBeverages({
462
+ companionType: (_b = options.companionTypes) == null ? void 0 : _b.beverage,
463
+ onBeverageSelected,
464
+ onClearBeverage: onBeverageCleared,
465
+ onBeverageListUpdated
466
+ });
467
+ const {
468
+ clearFlavors,
469
+ flavors,
470
+ selectFlavor,
471
+ selectedFlavors,
472
+ flavorCompanions
473
+ } = useFlavors({
474
+ companionType: (_c = options.companionTypes) == null ? void 0 : _c.flavor,
475
+ onFlavorSelected,
476
+ onFlavorCleared
477
+ });
478
+ const [onBeforePour, setOnBeforePour] = React.useState();
479
+ const updateOnBeforePour = React.useCallback((callback) => {
480
+ setOnBeforePour(() => callback);
481
+ }, []);
482
+ const pour = useNozzlePour({
483
+ onPour,
484
+ onPourCancel,
485
+ onBeforePour: handleBeforePour,
486
+ onBeforePourRejected: handleBeforePourRejected
487
+ });
488
+ updatePourContext.current = pour.updatePourContext;
489
+ removeFromPourContext.current = pour.removeFromPourContext;
490
+ const back = React.useCallback(() => {
491
+ log$2.debug(`Navigating back from group: ${currentGroup}`);
492
+ switch (currentGroup) {
493
+ case DISPENSE_GROUP_BRAND:
494
+ clearBeverage();
495
+ clearBrand();
496
+ break;
497
+ case DISPENSE_GROUP_BEVERAGE:
498
+ case DISPENSE_GROUP_FLAVOR:
499
+ setCurrentGroup(initialGroup);
500
+ clearBeverage();
501
+ clearBrand();
502
+ break;
503
+ }
504
+ }, [clearBeverage, clearBrand, currentGroup, initialGroup]);
505
+ const home = React.useCallback(() => {
506
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/home/`;
507
+ kosUiSdk.EventBus.publish(topic, {});
508
+ setCurrentGroup(initialGroup);
509
+ if (initialGroup === DISPENSE_GROUP_BRAND) {
510
+ clearBeverage();
511
+ clearBrand();
512
+ }
513
+ if (initialGroup === DISPENSE_GROUP_BEVERAGE) {
514
+ clearBeverage();
515
+ }
516
+ }, [clearBeverage, clearBrand, initialGroup]);
517
+ const pauseTimers = React.useCallback(() => {
518
+ if (timersRef.current.length === 0) {
519
+ log$2.debug("No timers to pause.");
520
+ return;
521
+ }
522
+ log$2.debug(`Pausing ${timersRef.current.length} timers.`);
523
+ timersRef.current.forEach((timer) => {
524
+ log$2.debug(`Pausing timer with id ${timer.id}.`);
525
+ timer.pause();
526
+ });
527
+ }, []);
528
+ const restartTimers = React.useCallback(() => {
529
+ if (timersRef.current.length === 0) {
530
+ log$2.debug("No timers to restart.");
531
+ return;
532
+ }
533
+ log$2.debug(`Restarting ${timersRef.current.length} timers.`);
534
+ timersRef.current.forEach((timer) => {
535
+ log$2.debug(`Restarting timer with id ${timer.id}.`);
536
+ timer.restart();
537
+ });
538
+ }, []);
539
+ const addTimer = React.useCallback((timer) => {
540
+ if (!timer) {
541
+ return;
542
+ }
543
+ if (timersRef.current.some((t) => t.id === timer.id)) {
544
+ log$2.debug(`Timer with id ${timer.id} already exists.`);
545
+ return;
546
+ }
547
+ timersRef.current.push(timer);
548
+ }, []);
549
+ return {
550
+ timers: {
551
+ add: addTimer,
552
+ pause: pauseTimers,
553
+ restart: restartTimers
554
+ },
555
+ nav: {
556
+ currentGroup,
557
+ back,
558
+ home
559
+ },
560
+ pour,
561
+ updateOnBeforePour,
562
+ selections: {
563
+ [DISPENSE_GROUP_BRAND]: selectedBrand,
564
+ [DISPENSE_GROUP_BEVERAGE]: selectedBeverage,
565
+ [DISPENSE_GROUP_FLAVOR]: selectedFlavors
566
+ },
567
+ [DISPENSE_GROUP_BRAND]: {
568
+ models: brands,
569
+ companions: brandCompanions,
570
+ clear: clearBrand,
571
+ handlers: {
572
+ onSelected: selectBrand
573
+ }
574
+ },
575
+ [DISPENSE_GROUP_BEVERAGE]: {
576
+ models: beverages,
577
+ companions: beverageCompanions,
578
+ clear: clearBeverage,
579
+ handlers: {
580
+ onSelected: selectBeverage
581
+ }
582
+ },
583
+ [DISPENSE_GROUP_FLAVOR]: {
584
+ models: flavors,
585
+ companions: flavorCompanions,
586
+ clear: clearFlavors,
587
+ handlers: {
588
+ onSelected: selectFlavor
589
+ }
590
+ }
591
+ };
592
+ };
593
+ const useAmbientAttractTimers = (props) => {
594
+ const { model: nozzle } = useNozzleContext();
595
+ const [attractTimer, setAttractTimer] = React.useState(null);
596
+ const {
597
+ onAmbientTimer,
598
+ onAttractTimer,
599
+ onResetAttractTimer,
600
+ onResumeAttractTimer,
601
+ defaultAttractTime,
602
+ defaultAmbientTime
603
+ } = props;
604
+ const handleAmbientTimer = React.useCallback(() => {
605
+ if (onAmbientTimer) {
606
+ kosUiSdk.KosLog.info("Ambient timer expired. Calling callback");
607
+ onAmbientTimer == null ? void 0 : onAmbientTimer();
608
+ }
609
+ }, [onAmbientTimer]);
610
+ const handleAttractTimer = React.useCallback(() => {
611
+ if (onAttractTimer) {
612
+ kosUiSdk.KosLog.info("Attract timer expired. Calling callback");
613
+ onAttractTimer == null ? void 0 : onAttractTimer();
614
+ }
615
+ }, [onAttractTimer]);
616
+ const handleResetAttractTimer = React.useCallback(() => {
617
+ if (attractTimer) {
618
+ attractTimer.restart();
619
+ onResetAttractTimer == null ? void 0 : onResetAttractTimer();
620
+ }
621
+ }, [attractTimer, onResetAttractTimer]);
622
+ const handlePauseAttractTimer = React.useCallback(() => {
623
+ if (attractTimer) {
624
+ attractTimer.reset();
625
+ onResetAttractTimer == null ? void 0 : onResetAttractTimer();
626
+ }
627
+ }, [attractTimer, onResetAttractTimer]);
628
+ const handleResume = React.useCallback(() => {
629
+ if (attractTimer) {
630
+ attractTimer.pause();
631
+ onResumeAttractTimer == null ? void 0 : onResumeAttractTimer();
632
+ }
633
+ }, [attractTimer, onResumeAttractTimer]);
634
+ React.useEffect(() => {
635
+ if (nozzle && defaultAttractTime) {
636
+ kosUiSdk.KosLog.info("Nozzle is available. Creating timers");
637
+ const timer = kosUiSdk.TimerManager.createTimer(
638
+ "attract-timer-" + nozzle.path,
639
+ defaultAttractTime
640
+ );
641
+ if (defaultAttractTime) {
642
+ timer == null ? void 0 : timer.addTimeoutAction({
643
+ name: "attract-timer",
644
+ remainingTime: 0,
645
+ action: handleAttractTimer
646
+ });
647
+ }
648
+ if (defaultAmbientTime) {
649
+ timer == null ? void 0 : timer.addTimeoutAction({
650
+ name: "ambient-timer",
651
+ remainingTime: defaultAmbientTime,
652
+ action: handleAmbientTimer
653
+ });
654
+ }
655
+ if (defaultAttractTime) {
656
+ timer == null ? void 0 : timer.start();
657
+ }
658
+ setAttractTimer(timer ?? null);
659
+ return () => {
660
+ timer == null ? void 0 : timer.reset();
661
+ setAttractTimer(null);
662
+ };
663
+ }
664
+ return () => {
665
+ kosUiSdk.KosLog.info("Nozzle is not available. No timers to clear");
666
+ };
667
+ }, [
668
+ defaultAmbientTime,
669
+ defaultAttractTime,
670
+ handleAmbientTimer,
671
+ handleAttractTimer,
672
+ nozzle
673
+ ]);
674
+ return {
675
+ attractTimer,
676
+ restart: handleResetAttractTimer,
677
+ pause: handlePauseAttractTimer,
678
+ resume: handleResume
679
+ };
680
+ };
681
+ const DISPENSE_EVENT_CONFIGS = [
682
+ { path: "brand/selected", callbackKey: "onBrandSelected" },
683
+ { path: "brand/cleared", callbackKey: "onBrandCleared" },
684
+ { path: "beverage/list/updated", callbackKey: "onBeverageListUpdated" },
685
+ { path: "beverage/selected", callbackKey: "onBeverageSelected" },
686
+ { path: "beverage/cleared", callbackKey: "onBeverageCleared" },
687
+ { path: "flavor/selected", callbackKey: "onFlavorSelected" },
688
+ { path: "flavor/cleared", callbackKey: "onFlavorCleared" },
689
+ { path: "pour", callbackKey: "onPour" },
690
+ { path: "pour/cancel", callbackKey: "onPourCancel" },
691
+ { path: "pre/pour/rejected", callbackKey: "onBeforePourRejected" },
692
+ { path: "ambient/start", callbackKey: "onAmbientTimer" },
693
+ { path: "attract/start", callbackKey: "onAttractTimer" },
694
+ { path: "attract/resume", callbackKey: "onResumeAttractTimer" },
695
+ { path: "idle/timeout", callbackKey: "onIdleTimeout" },
696
+ { path: "are-you-there/timeout", callbackKey: "onAreYouThereTimeout" },
697
+ { path: "init", callbackKey: "onInit" },
698
+ { path: "home", callbackKey: "onReturnToHome" }
699
+ ];
700
+ function buildDispenseTopics(nozzlePath, callbacks) {
701
+ if (!nozzlePath) {
702
+ return [];
703
+ }
704
+ return DISPENSE_EVENT_CONFIGS.filter(
705
+ (config) => callbacks[config.callbackKey] !== void 0
706
+ ).map((config) => {
707
+ return {
708
+ topic: `/kos/dispense/${nozzlePath}/${config.path}/`,
709
+ callback: callbacks[config.callbackKey]
710
+ };
711
+ });
712
+ }
713
+ const subscribe = (topic, callback) => {
714
+ if (callback) {
715
+ const callbackWrapper = (args) => {
716
+ if (args && args.body) {
717
+ callback(args.body);
718
+ }
719
+ };
720
+ const result = kosUiSdk.EventBus.subscribe(topic, callbackWrapper);
721
+ return result.unsubscribe;
722
+ }
723
+ return void 0;
724
+ };
725
+ const useDispenseLifecycle = ({
726
+ onInit,
727
+ onBrandSelected,
728
+ onBrandCleared,
729
+ onBeverageCleared,
730
+ onBeverageSelected,
731
+ onBeverageListUpdated,
732
+ onFlavorCleared,
733
+ onFlavorSelected,
734
+ onReturnToHome,
735
+ onPour,
736
+ onPourCancel,
737
+ onBeforePourRejected,
738
+ onAmbientTimer,
739
+ onAttractTimer,
740
+ onResumeAttractTimer,
741
+ onIdleTimeout,
742
+ onAreYouThereTimeout
743
+ }) => {
744
+ const { model: nozzle } = useNozzleContext();
745
+ React.useEffect(() => {
746
+ const topics = buildDispenseTopics(nozzle == null ? void 0 : nozzle.path, {
747
+ onBrandSelected,
748
+ onBrandCleared,
749
+ onBeverageListUpdated,
750
+ onBeverageSelected,
751
+ onBeverageCleared,
752
+ onFlavorSelected,
753
+ onFlavorCleared,
754
+ onPour,
755
+ onPourCancel,
756
+ onBeforePourRejected,
757
+ onAmbientTimer,
758
+ onAttractTimer,
759
+ onResumeAttractTimer,
760
+ onIdleTimeout,
761
+ onAreYouThereTimeout,
762
+ onInit,
763
+ onReturnToHome
764
+ });
765
+ const disposers = topics.map(
766
+ ({ topic, callback }) => subscribe(topic, callback)
767
+ );
768
+ return () => {
769
+ disposers.forEach((disposer) => disposer == null ? void 0 : disposer());
770
+ };
771
+ }, [
772
+ nozzle == null ? void 0 : nozzle.path,
773
+ onAmbientTimer,
774
+ onAttractTimer,
775
+ onBeverageCleared,
776
+ onBeverageSelected,
777
+ onBeverageListUpdated,
778
+ onBrandCleared,
779
+ onBrandSelected,
780
+ onFlavorCleared,
781
+ onFlavorSelected,
782
+ onPour,
783
+ onPourCancel,
784
+ onBeforePourRejected,
785
+ onResumeAttractTimer,
786
+ onIdleTimeout,
787
+ onAreYouThereTimeout,
788
+ onInit,
789
+ onReturnToHome
790
+ ]);
791
+ };
792
+ const log$1 = kosUiSdk.KosLog.createLogger({ name: "useCuiKitTimers" });
793
+ const useCuiKitTimers = (props) => {
794
+ const { model: nozzle } = useNozzleContext();
795
+ const [idleTimer, setIdleTimer] = React.useState(null);
796
+ const {
797
+ onAreYouThereTimer,
798
+ onIdleTimer,
799
+ onResetIdleTimer,
800
+ defaultAreYouThereTime = 10,
801
+ defaultIdleTime = 20
802
+ } = props;
803
+ const hasAreYouThereFiredRef = React.useRef(false);
804
+ const handleAreYouThereTimer = React.useCallback(() => {
805
+ if (!hasAreYouThereFiredRef.current && onAreYouThereTimer) {
806
+ kosUiSdk.KosLog.info("Are you there timer expired. Calling callback");
807
+ hasAreYouThereFiredRef.current = true;
808
+ onAreYouThereTimer == null ? void 0 : onAreYouThereTimer();
809
+ }
810
+ }, [onAreYouThereTimer]);
811
+ const handleIdleTimer = React.useCallback(() => {
812
+ log$1.debug(
813
+ "handleIdleTimer called in useCuiKitTimers, onIdleTimer exists:",
814
+ !!onIdleTimer
815
+ );
816
+ if (onIdleTimer) {
817
+ log$1.debug("Idle timer expired. Calling callback");
818
+ onIdleTimer == null ? void 0 : onIdleTimer();
819
+ } else {
820
+ log$1.debug("No onIdleTimer callback provided!");
821
+ }
822
+ }, [onIdleTimer]);
823
+ const handleRestartIdleTimer = React.useCallback(() => {
824
+ log$1.debug(`TIMER RESTART called for ${props.prefix ?? ""}timer`);
825
+ if (idleTimer) {
826
+ idleTimer.restart();
827
+ hasAreYouThereFiredRef.current = false;
828
+ onResetIdleTimer == null ? void 0 : onResetIdleTimer();
829
+ }
830
+ }, [idleTimer, onResetIdleTimer, props.prefix]);
831
+ const handlePauseIdleTimer = React.useCallback(() => {
832
+ log$1.debug(`TIMER PAUSE/RESET called for ${props.prefix ?? ""}timer`);
833
+ if (idleTimer) {
834
+ idleTimer.reset();
835
+ hasAreYouThereFiredRef.current = false;
836
+ onResetIdleTimer == null ? void 0 : onResetIdleTimer();
837
+ }
838
+ }, [idleTimer, onResetIdleTimer, props.prefix]);
839
+ React.useEffect(() => {
840
+ log$1.debug(
841
+ `useCuiKitTimers effect triggered - nozzle: ${!!nozzle}, path: ${nozzle == null ? void 0 : nozzle.path}, callbacks: handleIdle=${!!handleIdleTimer}, handleAreYouThere=${!!handleAreYouThereTimer}`
842
+ );
843
+ if (nozzle) {
844
+ log$1.info("Nozzle is available. Creating timers");
845
+ const timer = kosUiSdk.TimerManager.createTimer(
846
+ `${props.prefix ?? ""}idle-timer-${nozzle.path}`,
847
+ defaultIdleTime
848
+ );
849
+ log$1.debug(
850
+ `Adding idle timer action for ${props.prefix ?? ""}idle-timer-${nozzle.path} with callback:`,
851
+ !!handleIdleTimer
852
+ );
853
+ timer == null ? void 0 : timer.addTimeoutAction({
854
+ name: "idle-timer",
855
+ remainingTime: 0,
856
+ action: handleIdleTimer
857
+ });
858
+ timer == null ? void 0 : timer.addTimeoutAction({
859
+ name: "are-you-there-timer",
860
+ remainingTime: defaultAreYouThereTime,
861
+ action: handleAreYouThereTimer
862
+ });
863
+ setIdleTimer(timer ?? null);
864
+ return () => {
865
+ timer == null ? void 0 : timer.reset();
866
+ setIdleTimer(null);
867
+ };
868
+ }
869
+ return () => {
870
+ log$1.info("Nozzle is not available. No timers to clear");
871
+ };
872
+ }, [
873
+ defaultAreYouThereTime,
874
+ defaultIdleTime,
875
+ handleAreYouThereTimer,
876
+ handleIdleTimer,
877
+ nozzle,
878
+ props.prefix
879
+ ]);
880
+ return {
881
+ idleTimer,
882
+ restart: handleRestartIdleTimer,
883
+ pause: handlePauseIdleTimer
884
+ };
885
+ };
886
+ const log = kosUiSdk.KosLog.createLogger({ name: "useDefaultCuiKitLifecycle" });
887
+ const useDefaultCuiKitLifecycle = ({
888
+ kit,
889
+ inactivity,
890
+ pour,
891
+ screens,
892
+ onBeforeAreYouThereTimer,
893
+ areYouThereRejectionPolicy = "pause"
894
+ }) => {
895
+ var _a, _b, _c, _d;
896
+ const [showAmbientScreen, setShowAmbientScreen] = React.useState(false);
897
+ const [showAttractScreen, setShowAttractScreen] = React.useState(false);
898
+ const { model: nozzle } = useNozzleContext();
899
+ const [hasPoured, setHasPoured] = React.useState(false);
900
+ const idleTimeout = (inactivity == null ? void 0 : inactivity.idleTimeout) ?? 15;
901
+ const areYouThereTimeout = (inactivity == null ? void 0 : inactivity.areYouThereTimeoutOffset) ?? 10;
902
+ const idlePourTimeout = (pour == null ? void 0 : pour.idleTimeout) ?? (inactivity == null ? void 0 : inactivity.idleTimeout) ?? 10;
903
+ const areYouTherePourTimeout = (pour == null ? void 0 : pour.areYouThereTimeoutOffset) ?? (inactivity == null ? void 0 : inactivity.areYouThereTimeoutOffset) ?? 5;
904
+ const ambientTimeout = screens == null ? void 0 : screens.ambientTimeoutOffset;
905
+ const attractTimeout = screens == null ? void 0 : screens.attractTimeout;
906
+ const handleIdleTimeout = React.useCallback(() => {
907
+ log.info("handleIdleTimeout called - navigating home and publishing event");
908
+ setShowAreYouThere(false);
909
+ kit == null ? void 0 : kit.nav.home();
910
+ if (nozzle) {
911
+ const topic = `/kos/dispense/${nozzle.path}/idle/timeout/`;
912
+ kosUiSdk.EventBus.publish(topic, {});
913
+ }
914
+ }, [(_a = kit == null ? void 0 : kit.nav) == null ? void 0 : _a.home, nozzle]);
915
+ const handleResetIdleTimer = React.useCallback(() => {
916
+ log.info("handleResetIdleTimer called - resetting idle timer");
917
+ setShowAreYouThere(false);
918
+ }, []);
919
+ const handleAmbientTimer = React.useCallback(() => {
920
+ if (ambientTimeout) {
921
+ setShowAmbientScreen(true);
922
+ setShowAttractScreen(false);
923
+ if (nozzle) {
924
+ const topic = `/kos/dispense/${nozzle.path}/ambient/start/`;
925
+ kosUiSdk.EventBus.publish(topic, {});
926
+ }
927
+ }
928
+ }, [ambientTimeout, nozzle]);
929
+ const handleAttractTimer = React.useCallback(() => {
930
+ if (attractTimeout) {
931
+ setShowAttractScreen(true);
932
+ setShowAmbientScreen(false);
933
+ if (nozzle) {
934
+ const topic = `/kos/dispense/${nozzle.path}/attract/start/`;
935
+ kosUiSdk.EventBus.publish(topic, {});
936
+ }
937
+ }
938
+ }, [attractTimeout, nozzle]);
939
+ const handleAttractResume = React.useCallback(() => {
940
+ if (attractTimeout) {
941
+ setShowAttractScreen(false);
942
+ setShowAmbientScreen(false);
943
+ kit == null ? void 0 : kit.nav.home();
944
+ if (nozzle) {
945
+ const topic = `/kos/dispense/${nozzle.path}/attract/resume/`;
946
+ kosUiSdk.EventBus.publish(topic, {});
947
+ }
948
+ }
949
+ }, [kit == null ? void 0 : kit.nav, attractTimeout, nozzle]);
950
+ const {
951
+ pause: ambientPause,
952
+ restart: ambientRestart,
953
+ attractTimer
954
+ } = useAmbientAttractTimers({
955
+ defaultAmbientTime: ambientTimeout,
956
+ defaultAttractTime: attractTimeout,
957
+ onAmbientTimer: handleAmbientTimer,
958
+ onAttractTimer: handleAttractTimer,
959
+ onResumeAttractTimer: handleAttractResume
960
+ });
961
+ (_b = kit == null ? void 0 : kit.timers) == null ? void 0 : _b.add(attractTimer);
962
+ const [showAreYouThere, setShowAreYouThere] = React.useState(false);
963
+ log.info(
964
+ "Creating idle timer with timeout:",
965
+ idleTimeout,
966
+ "seconds and callback:",
967
+ !!handleIdleTimeout
968
+ );
969
+ const { pause, restart, idleTimer } = useCuiKitTimers({
970
+ defaultAreYouThereTime: areYouThereTimeout,
971
+ defaultIdleTime: idleTimeout,
972
+ onIdleTimer: handleIdleTimeout,
973
+ onResetIdleTimer: handleResetIdleTimer
974
+ });
975
+ log.info(
976
+ `Creating pour timer with timeout: ${idlePourTimeout} seconds and callback: ${!!handleIdleTimeout}`
977
+ );
978
+ const {
979
+ pause: pausePourTimer,
980
+ restart: restartPourTimer,
981
+ idleTimer: pourIdleTimer
982
+ } = useCuiKitTimers({
983
+ defaultAreYouThereTime: areYouTherePourTimeout,
984
+ defaultIdleTime: idlePourTimeout,
985
+ onIdleTimer: handleIdleTimeout,
986
+ prefix: "pour-"
987
+ });
988
+ const handleAreYouThereTimer = React.useCallback(async () => {
989
+ let shouldShowAreYouThere = true;
990
+ if (onBeforeAreYouThereTimer) {
991
+ try {
992
+ shouldShowAreYouThere = await onBeforeAreYouThereTimer();
993
+ } catch (error) {
994
+ log.error(`onBeforeAreYouThereTimer callback failed: ${error}`);
995
+ shouldShowAreYouThere = false;
996
+ }
997
+ }
998
+ if (shouldShowAreYouThere) {
999
+ if (nozzle) {
1000
+ const topic = `/kos/dispense/${nozzle.path}/are-you-there/timeout/`;
1001
+ kosUiSdk.EventBus.publish(topic, {});
1002
+ }
1003
+ setShowAreYouThere(true);
1004
+ if (hasPoured) {
1005
+ pausePourTimer();
1006
+ } else {
1007
+ pause();
1008
+ }
1009
+ } else {
1010
+ switch (areYouThereRejectionPolicy) {
1011
+ case "pause":
1012
+ if (hasPoured) {
1013
+ pausePourTimer();
1014
+ } else {
1015
+ pause();
1016
+ }
1017
+ break;
1018
+ case "restart":
1019
+ if (hasPoured) {
1020
+ restartPourTimer();
1021
+ } else {
1022
+ restart();
1023
+ }
1024
+ break;
1025
+ }
1026
+ }
1027
+ }, [onBeforeAreYouThereTimer, nozzle, areYouThereRejectionPolicy, hasPoured]);
1028
+ const clearAreYouThere = React.useCallback(() => {
1029
+ setShowAreYouThere(false);
1030
+ ambientPause();
1031
+ if (hasPoured) {
1032
+ restartPourTimer();
1033
+ pause();
1034
+ } else {
1035
+ restart();
1036
+ pausePourTimer();
1037
+ }
1038
+ }, [hasPoured, pause, pausePourTimer, restart, restartPourTimer]);
1039
+ React.useEffect(() => {
1040
+ if (idleTimer) {
1041
+ idleTimer.addTimeoutAction({
1042
+ name: "are-you-there-timer",
1043
+ remainingTime: areYouThereTimeout,
1044
+ action: handleAreYouThereTimer
1045
+ });
1046
+ }
1047
+ }, [idleTimer, areYouThereTimeout, handleAreYouThereTimer]);
1048
+ React.useEffect(() => {
1049
+ if (pourIdleTimer) {
1050
+ pourIdleTimer.addTimeoutAction({
1051
+ name: "pour-are-you-there-timer",
1052
+ remainingTime: areYouTherePourTimeout,
1053
+ action: handleAreYouThereTimer
1054
+ });
1055
+ }
1056
+ }, [pourIdleTimer, areYouTherePourTimeout, handleAreYouThereTimer]);
1057
+ (_c = kit == null ? void 0 : kit.timers) == null ? void 0 : _c.add(idleTimer);
1058
+ (_d = kit == null ? void 0 : kit.timers) == null ? void 0 : _d.add(pourIdleTimer);
1059
+ const handlePour = React.useCallback(() => {
1060
+ setHasPoured(false);
1061
+ pausePourTimer();
1062
+ pause();
1063
+ ambientPause();
1064
+ }, [pause, pausePourTimer]);
1065
+ const handlePourCancel = React.useCallback(() => {
1066
+ setHasPoured(true);
1067
+ log.info("restarting pour timer");
1068
+ restartPourTimer();
1069
+ ambientPause();
1070
+ pause();
1071
+ }, [pause, restartPourTimer]);
1072
+ const handleBeforePourRejected = React.useCallback(() => {
1073
+ setHasPoured(false);
1074
+ log.info("restarting pour timer on before pour rejected");
1075
+ pausePourTimer();
1076
+ restart();
1077
+ }, []);
1078
+ const handleBrandSelected = React.useCallback(() => {
1079
+ ambientPause();
1080
+ setShowAttractScreen(false);
1081
+ setShowAmbientScreen(false);
1082
+ restart();
1083
+ }, [ambientPause, restart]);
1084
+ const handleBrandCleared = React.useCallback(() => {
1085
+ setShowAttractScreen(false);
1086
+ setShowAmbientScreen(false);
1087
+ setHasPoured(false);
1088
+ pausePourTimer();
1089
+ ambientRestart();
1090
+ }, [ambientRestart, pausePourTimer]);
1091
+ const handleBeverageSelected = React.useCallback(() => {
1092
+ setShowAttractScreen(false);
1093
+ setShowAmbientScreen(false);
1094
+ setHasPoured(false);
1095
+ ambientPause();
1096
+ restart();
1097
+ }, [ambientPause, restart]);
1098
+ const handleBeverageCleared = React.useCallback(() => {
1099
+ setShowAttractScreen(false);
1100
+ setShowAmbientScreen(false);
1101
+ setHasPoured(false);
1102
+ ambientRestart();
1103
+ pause();
1104
+ pausePourTimer();
1105
+ }, [ambientRestart, pause, pausePourTimer]);
1106
+ const handleInit = React.useCallback(() => {
1107
+ setShowAttractScreen(false);
1108
+ setShowAmbientScreen(false);
1109
+ ambientRestart();
1110
+ pause();
1111
+ }, [ambientRestart, pause]);
1112
+ useDispenseLifecycle({
1113
+ onBrandSelected: handleBrandSelected,
1114
+ onBrandCleared: handleBrandCleared,
1115
+ onBeverageSelected: handleBeverageSelected,
1116
+ onBeverageCleared: handleBeverageCleared,
1117
+ onPour: handlePour,
1118
+ onPourCancel: handlePourCancel,
1119
+ onBeforePourRejected: handleBeforePourRejected,
1120
+ onInit: handleInit
1121
+ // Note: Timer-related handlers (onIdleTimeout, onAmbientTimer, onAttractTimer,
1122
+ // onResumeAttractTimer, onAreYouThereTimeout) are NOT included here since this
1123
+ // component's own timer hooks call those handlers directly. Including them would
1124
+ // create circular event loops.
1125
+ });
1126
+ const areYouThereCountdown = hasPoured ? areYouTherePourTimeout : areYouThereTimeout;
1127
+ React.useEffect(() => {
1128
+ if (nozzle && attractTimer) {
1129
+ const topic = `/kos/dispense/${nozzle == null ? void 0 : nozzle.path}/init/`;
1130
+ kosUiSdk.EventBus.publish(topic, {});
1131
+ }
1132
+ }, [nozzle, attractTimer]);
1133
+ return {
1134
+ showAreYouThere,
1135
+ clearAreYouThere,
1136
+ pauseIdleTimer: pause,
1137
+ restartIdleTimer: restart,
1138
+ areYouThereCountdown,
1139
+ showAmbientScreen,
1140
+ showAttractScreen,
1141
+ pauseScreenTimer: ambientPause,
1142
+ restartScreenTimer: ambientRestart
1143
+ };
1144
+ };
1145
+ const useDeviceAssembly = () => {
1146
+ const modelId = dispenseRegistrationManager.DeviceAssembly.type;
1147
+ const result = kosUiSdk.useKosModel({
1148
+ modelId,
1149
+ modelType: dispenseRegistrationManager.DeviceAssembly.type,
1150
+ options: {}
1151
+ });
1152
+ return result;
1153
+ };
1154
+ function withDeviceAssembly(WrappedComponent) {
1155
+ return (props) => {
1156
+ const { model, status, KosModelLoader } = useDeviceAssembly();
1157
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, deviceAssembly: model }) });
1158
+ };
1159
+ }
1160
+ const useHolder = (id) => {
1161
+ const modelId = id;
1162
+ const result = kosUiSdk.useKosModel({
1163
+ modelId,
1164
+ modelType: dispenseRegistrationManager.Holder.type,
1165
+ options: {}
1166
+ });
1167
+ return result;
1168
+ };
1169
+ function withHolder(id, WrappedComponent) {
1170
+ return (props) => {
1171
+ const { model, status, KosModelLoader } = useHolder(id);
1172
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, holder: model }) });
1173
+ };
1174
+ }
1175
+ const useHolderContainer = () => {
1176
+ const modelId = dispenseRegistrationManager.HolderContainer.type;
1177
+ const result = kosUiSdk.useKosModel({
1178
+ modelId,
1179
+ modelType: dispenseRegistrationManager.HolderContainer.type,
1180
+ options: {}
1181
+ });
1182
+ return result;
1183
+ };
1184
+ function withHolderContainer(WrappedComponent) {
1185
+ return (props) => {
1186
+ const { model, status, KosModelLoader } = useHolderContainer();
1187
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, holderContainer: model }) });
1188
+ };
1189
+ }
1190
+ const useIngredient = () => {
1191
+ const modelId = dispenseRegistrationManager.Ingredient.type;
1192
+ const result = kosUiSdk.useKosModel({
1193
+ modelId,
1194
+ modelType: dispenseRegistrationManager.Ingredient.type,
1195
+ options: {}
1196
+ });
1197
+ return result;
1198
+ };
1199
+ const logger$5 = kosUiSdk.KosLog.createLogger({
1200
+ name: "HoldToPourIntentStrategy",
1201
+ group: "kos-hooks"
1202
+ });
1203
+ const HoldToPourIntentStrategy = {
1204
+ name: "HoldToPourIntentStrategy",
1205
+ async initiate(model, intent) {
1206
+ if (!(model == null ? void 0 : model.canPour)) {
1207
+ logger$5.debug(`${model == null ? void 0 : model.id} cannot pour. Returning early.`);
1208
+ return;
1209
+ }
1210
+ if (intent) {
1211
+ logger$5.debug(`performing intent: ${intent}`);
1212
+ await (model == null ? void 0 : model.performIntent(intent));
1213
+ } else {
1214
+ logger$5.debug("no intent provided. Returning early.");
1215
+ }
1216
+ },
1217
+ async initiateEnded(nozzle) {
1218
+ await (nozzle == null ? void 0 : nozzle.cancelPour());
1219
+ }
1220
+ };
1221
+ const logger$4 = kosUiSdk.KosLog.createLogger({
1222
+ name: "useNozzlePour",
1223
+ group: "kos-hooks"
1224
+ });
1225
+ const useIngredientPour = ({
1226
+ onPour,
1227
+ onPourCancel,
1228
+ intentContainer,
1229
+ strategy = HoldToPourIntentStrategy
1230
+ }) => {
1231
+ const handlePour = React.useCallback(() => {
1232
+ logger$4.debug(
1233
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiated for model ${intentContainer == null ? void 0 : intentContainer.id}.`
1234
+ );
1235
+ strategy == null ? void 0 : strategy.initiate(intentContainer);
1236
+ onPour == null ? void 0 : onPour();
1237
+ }, [onPour, intentContainer, strategy]);
1238
+ const handleCancelPour = React.useCallback(() => {
1239
+ var _a;
1240
+ logger$4.debug(
1241
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiate ended called for nozzle ${intentContainer == null ? void 0 : intentContainer.id}.`
1242
+ );
1243
+ (_a = strategy == null ? void 0 : strategy.initiateEnded) == null ? void 0 : _a.call(strategy, intentContainer);
1244
+ onPourCancel == null ? void 0 : onPourCancel();
1245
+ }, [onPourCancel, intentContainer, strategy]);
1246
+ const forceCancelPour = React.useCallback(() => {
1247
+ logger$4.debug(`Force cancelling pour for nozzle ${intentContainer == null ? void 0 : intentContainer.id}.`);
1248
+ intentContainer == null ? void 0 : intentContainer.cancelPour();
1249
+ onPourCancel == null ? void 0 : onPourCancel();
1250
+ }, [onPourCancel, intentContainer]);
1251
+ const handlers = kosUiSdk.usePressGesture({
1252
+ onPressed: handlePour,
1253
+ onRelease: handleCancelPour
1254
+ });
1255
+ return {
1256
+ handlers: handlers.dom,
1257
+ cancel: forceCancelPour,
1258
+ status: intentContainer
1259
+ };
1260
+ };
1261
+ function withIngredient(WrappedComponent) {
1262
+ return (props) => {
1263
+ const { model, status, KosModelLoader } = useIngredient();
1264
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, ingredient: model }) });
1265
+ };
1266
+ }
1267
+ const useIngredientContainer = () => {
1268
+ const modelId = dispenseRegistrationManager.IngredientContainer.type;
1269
+ const result = kosUiSdk.useKosModel({
1270
+ modelId,
1271
+ modelType: dispenseRegistrationManager.IngredientContainer.type,
1272
+ options: {}
1273
+ });
1274
+ return result;
1275
+ };
1276
+ function withIngredientContainer(WrappedComponent) {
1277
+ return (props) => {
1278
+ const { model, status, KosModelLoader } = useIngredientContainer();
1279
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, ingredientContainer: model }) });
1280
+ };
1281
+ }
1282
+ function withNozzle(path, WrappedComponent) {
1283
+ return (props) => {
1284
+ const { model, status, KosModelLoader } = useNozzle(path);
1285
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, nozzle: model }) });
1286
+ };
1287
+ }
1288
+ const logger$3 = kosUiSdk.KosLog.createLogger({
1289
+ name: "usePour",
1290
+ group: "kos-hooks"
1291
+ });
1292
+ const usePourTarget = ({
1293
+ onBeforePour,
1294
+ onPour,
1295
+ onPourCancel,
1296
+ onPourAbort,
1297
+ pourTarget,
1298
+ pourContext,
1299
+ strategy = HoldToPourStrategy
1300
+ }) => {
1301
+ const [context, _setContext] = React.useState(
1302
+ pourContext || new PourContext()
1303
+ );
1304
+ const handlePour = React.useCallback(async () => {
1305
+ logger$3.debug(
1306
+ `[${strategy == null ? void 0 : strategy.name}] - calling before pour for pour target ${pourTarget == null ? void 0 : pourTarget.id}.`
1307
+ );
1308
+ const canPour = onBeforePour ? await (onBeforePour == null ? void 0 : onBeforePour(context)) : true;
1309
+ if (canPour) {
1310
+ logger$3.debug(
1311
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiated for pour target ${pourTarget == null ? void 0 : pourTarget.id}.`
1312
+ );
1313
+ await (strategy == null ? void 0 : strategy.initiate(pourTarget));
1314
+ onPour == null ? void 0 : onPour();
1315
+ if (!(pourTarget == null ? void 0 : pourTarget.isPouring)) {
1316
+ onPourAbort == null ? void 0 : onPourAbort();
1317
+ }
1318
+ } else {
1319
+ logger$3.debug(
1320
+ `[${strategy == null ? void 0 : strategy.name}] - Pour cancelled for pour target ${pourTarget == null ? void 0 : pourTarget.id}.`
1321
+ );
1322
+ onPourCancel == null ? void 0 : onPourCancel();
1323
+ }
1324
+ }, [onPour, onBeforePour, onPourAbort, pourTarget, strategy, context]);
1325
+ const handleCancelPour = React.useCallback(async () => {
1326
+ var _a;
1327
+ logger$3.debug(
1328
+ `[${strategy == null ? void 0 : strategy.name}] - Pour initiate ended called for pour target ${pourTarget == null ? void 0 : pourTarget.id}.`
1329
+ );
1330
+ const ignore = await ((_a = strategy == null ? void 0 : strategy.initiateEnded) == null ? void 0 : _a.call(strategy, pourTarget));
1331
+ if (!ignore) {
1332
+ onPourCancel == null ? void 0 : onPourCancel();
1333
+ }
1334
+ }, [onPourCancel, pourTarget, strategy]);
1335
+ const forceCancelPour = React.useCallback(async () => {
1336
+ logger$3.debug(`Force cancelling pour for pour target ${pourTarget == null ? void 0 : pourTarget.id}.`);
1337
+ await (pourTarget == null ? void 0 : pourTarget.cancelPour());
1338
+ onPourCancel == null ? void 0 : onPourCancel();
1339
+ }, [onPourCancel, pourTarget]);
1340
+ const handleUpdateContext = React.useCallback(
1341
+ (key, value) => {
1342
+ context.set(key, value);
1343
+ },
1344
+ [context]
1345
+ );
1346
+ const handleRemoveFromContext = React.useCallback(
1347
+ (key) => {
1348
+ context.remove(key);
1349
+ },
1350
+ [context]
1351
+ );
1352
+ const handlers = kosUiSdk.usePressGesture({
1353
+ onPressed: handlePour,
1354
+ onRelease: handleCancelPour
1355
+ });
1356
+ return {
1357
+ handlers: handlers.dom,
1358
+ cancel: forceCancelPour,
1359
+ updatePourContext: handleUpdateContext,
1360
+ removeFromPourContext: handleRemoveFromContext,
1361
+ status: pourTarget
1362
+ };
1363
+ };
1364
+ const logger$2 = kosUiSdk.KosLog.createLogger({
1365
+ name: "TapOrHoldIntentStrategy",
1366
+ group: "kos-hooks"
1367
+ });
1368
+ class TapOrHoldIntentStrategy {
1369
+ constructor(intent) {
1370
+ __publicField(this, "intent");
1371
+ __publicField(this, "name", "TapOrHoldIntentStrategy");
1372
+ __publicField(this, "isHold", false);
1373
+ __publicField(this, "disposer", null);
1374
+ this.intent = intent;
1375
+ }
1376
+ async initiate(model, intent) {
1377
+ this.disposer = setTimeout(() => {
1378
+ this.isHold = true;
1379
+ }, 250);
1380
+ if ((model == null ? void 0 : model.isPouring) && !this.isHold) {
1381
+ logger$2.debug(`additional tap detected. cancelling pour`);
1382
+ await model.cancelPour();
1383
+ return;
1384
+ }
1385
+ if (!(model == null ? void 0 : model.canPour)) {
1386
+ logger$2.debug(`${model == null ? void 0 : model.id} cannot pour. Returning early.`);
1387
+ return;
1388
+ }
1389
+ if (intent) {
1390
+ logger$2.debug(`performing intent: ${intent}`);
1391
+ await (model == null ? void 0 : model.performIntent(intent));
1392
+ } else {
1393
+ logger$2.debug("no intent provided. Returning early.");
1394
+ }
1395
+ }
1396
+ async initiateEnded(nozzle) {
1397
+ if (this.disposer)
1398
+ clearTimeout(this.disposer);
1399
+ this.disposer = null;
1400
+ if (!this.isHold) {
1401
+ logger$2.debug("Tap detected. don't cancel and return.");
1402
+ return true;
1403
+ }
1404
+ await (nozzle == null ? void 0 : nozzle.cancelPour());
1405
+ return false;
1406
+ }
1407
+ }
1408
+ const logger$1 = kosUiSdk.KosLog.createLogger({
1409
+ name: "TapToPourIntentStrategy",
1410
+ group: "kos-hooks"
1411
+ });
1412
+ const TapToPourIntentStrategy = {
1413
+ name: "TapToPourIntentStrategy",
1414
+ async initiate(model, intent) {
1415
+ if (model == null ? void 0 : model.isPouring) {
1416
+ logger$1.debug(`Nozzle ${model == null ? void 0 : model.id} is already pouring. cancelling pour`);
1417
+ await model.cancelPour();
1418
+ return;
1419
+ }
1420
+ if (!(model == null ? void 0 : model.canPour)) {
1421
+ logger$1.debug(`Nozzle ${model == null ? void 0 : model.id} cannot pour. Returning early.`);
1422
+ return;
1423
+ }
1424
+ if (intent) {
1425
+ logger$1.debug(`performing intent: ${intent}`);
1426
+ await (model == null ? void 0 : model.performIntent(intent));
1427
+ } else {
1428
+ logger$1.debug("no intent provided. Returning early.");
1429
+ }
1430
+ },
1431
+ async initiateEnded(_nozzle) {
1432
+ return true;
1433
+ }
1434
+ };
1435
+ const logger = kosUiSdk.KosLog.createLogger({
1436
+ name: "HoldToPourStrategy",
1437
+ group: "kos-hooks"
1438
+ });
1439
+ const TapToPourStrategy = {
1440
+ name: "TapToPourStrategy",
1441
+ async initiate(nozzle) {
1442
+ if (nozzle == null ? void 0 : nozzle.isPouring) {
1443
+ logger.debug(`Nozzle ${nozzle == null ? void 0 : nozzle.id} is already pouring. cancelling pour`);
1444
+ await nozzle.cancelPour();
1445
+ return;
1446
+ }
1447
+ if (!(nozzle == null ? void 0 : nozzle.canPour)) {
1448
+ logger.debug(`Nozzle ${nozzle == null ? void 0 : nozzle.id} cannot pour. Returning early.`);
1449
+ return;
1450
+ }
1451
+ await (nozzle == null ? void 0 : nozzle.pour());
1452
+ },
1453
+ async initiateEnded(_nozzle) {
1454
+ return true;
1455
+ }
1456
+ };
1457
+ const useGenericPour = (id, servicePathFactory, itemId, data) => {
1458
+ const modelId = id;
1459
+ const result = kosUiSdk.useKosModel({
1460
+ modelId,
1461
+ modelType: dispenseRegistrationManager.GenericPour.type,
1462
+ forceUpdate: true,
1463
+ options: {
1464
+ servicePathFactory,
1465
+ selectedId: itemId,
1466
+ initialData: data
1467
+ }
1468
+ });
1469
+ return result;
1470
+ };
1471
+ function withGenericPour(WrappedComponent) {
1472
+ return (props) => {
1473
+ const { model, status, KosModelLoader } = useGenericPour(
1474
+ props.id,
1475
+ props.servicePathFactory,
1476
+ props.itemId
1477
+ );
1478
+ return /* @__PURE__ */ jsxRuntime.jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props, genericPour: model }) });
1479
+ };
1480
+ }
1481
+ const Assembly = React.createContext(void 0);
1482
+ const AssemblyProvider = ({ children }) => {
1483
+ const { model, ready } = useAssembly();
1484
+ const value = React.useMemo(() => {
1485
+ if (ready && model) {
1486
+ return { model };
1487
+ }
1488
+ return {};
1489
+ }, [ready, model]);
1490
+ return /* @__PURE__ */ jsxRuntime.jsx(Assembly.Provider, { value, children });
1491
+ };
1492
+ const useAssemblyContext = () => {
1493
+ const context = React.useContext(
1494
+ Assembly
1495
+ );
1496
+ if (!context) {
1497
+ throw new Error(
1498
+ "useAssemblyContext must be used within a AssemblyProvider"
1499
+ );
1500
+ }
1501
+ return context;
1502
+ };
1503
+ const Availability = React.createContext(void 0);
1504
+ const AvailabilityProvider = ({ children }) => {
1505
+ const { model, ready } = useAvailability();
1506
+ const value = React.useMemo(() => {
1507
+ if (ready && model) {
1508
+ return { model };
1509
+ }
1510
+ return {};
1511
+ }, [ready, model]);
1512
+ return /* @__PURE__ */ jsxRuntime.jsx(Availability.Provider, { value, children });
1513
+ };
1514
+ const useAvailabilityContext = () => {
1515
+ const context = React.useContext(Availability);
1516
+ if (!context) {
1517
+ throw new Error(
1518
+ "useAvailabilityContext must be used within a AvailabilityProvider"
1519
+ );
1520
+ }
1521
+ return context;
1522
+ };
1523
+ const Board = React.createContext(void 0);
1524
+ const BoardProvider = ({ children, id }) => {
1525
+ const { model, ready } = useBoard(id);
1526
+ const value = React.useMemo(() => {
1527
+ if (ready && model) {
1528
+ return { model };
1529
+ }
1530
+ return {};
1531
+ }, [ready, model]);
1532
+ return /* @__PURE__ */ jsxRuntime.jsx(Board.Provider, { value, children });
1533
+ };
1534
+ const useBoardContext = () => {
1535
+ const context = React.useContext(Board);
1536
+ if (!context) {
1537
+ throw new Error("useBoardContext must be used within a BoardProvider");
1538
+ }
1539
+ return context;
1540
+ };
1541
+ const BoardContainer = React.createContext(void 0);
1542
+ const BoardContainerProvider = ({ children }) => {
1543
+ const { model, ready } = useBoardContainer();
1544
+ const value = React.useMemo(() => {
1545
+ if (ready && model) {
1546
+ return { model };
1547
+ }
1548
+ return {};
1549
+ }, [ready, model]);
1550
+ return /* @__PURE__ */ jsxRuntime.jsx(BoardContainer.Provider, { value, children });
1551
+ };
1552
+ const useBoardContainerContext = () => {
1553
+ const context = React.useContext(BoardContainer);
1554
+ if (!context) {
1555
+ throw new Error(
1556
+ "useBoardContainerContext must be used within a BoardContainerProvider"
1557
+ );
1558
+ }
1559
+ return context;
1560
+ };
1561
+ const DeviceAssemblyContext = React.createContext(
1562
+ void 0
1563
+ );
1564
+ const DeviceAssemblyProvider = ({ children }) => {
1565
+ const { model, ready } = useDeviceAssembly();
1566
+ const value = React.useMemo(() => {
1567
+ if (ready && model) {
1568
+ const nozzlePaths = model.nozzlePaths;
1569
+ return { model, nozzlePaths };
1570
+ }
1571
+ return {};
1572
+ }, [ready, model]);
1573
+ const content = ready && model ? children : null;
1574
+ return /* @__PURE__ */ jsxRuntime.jsx(DeviceAssemblyContext.Provider, { value, children: content });
1575
+ };
1576
+ const useDeviceAssemblyContext = () => {
1577
+ const context = React.useContext(DeviceAssemblyContext);
1578
+ if (!context) {
1579
+ throw new Error(
1580
+ "useDeviceAssemblyContext must be used within a DeviceAssemblyProvider"
1581
+ );
1582
+ }
1583
+ return context;
1584
+ };
1585
+ function createDispenseKitContext() {
1586
+ const CuiKitContext = React.createContext(null);
1587
+ const useCuiKitContext = () => {
1588
+ const ctx = React.useContext(CuiKitContext);
1589
+ if (ctx === void 0) {
1590
+ throw new Error("useDispenseKitContext must be used within a Provider");
1591
+ }
1592
+ return ctx;
1593
+ };
1594
+ return [useCuiKitContext, CuiKitContext.Provider];
1595
+ }
1596
+ function CuiKitWrapper({
1597
+ children,
1598
+ provider: CuiKitProvider,
1599
+ props,
1600
+ nozzleProps
1601
+ }) {
1602
+ const result = useCuiKit(props);
1603
+ return /* @__PURE__ */ jsxRuntime.jsx(CuiKitProvider, { value: result, children: children(nozzleProps || {}) });
1604
+ }
1605
+ function DispenseView({
1606
+ children,
1607
+ provider,
1608
+ props
1609
+ }) {
1610
+ const { nozzlePaths } = useDeviceAssemblyContext();
1611
+ const totalNozzles = (nozzlePaths == null ? void 0 : nozzlePaths.length) || 0;
1612
+ const nozzles = (nozzlePaths == null ? void 0 : nozzlePaths.map((path, index) => /* @__PURE__ */ jsxRuntime.jsx(NozzleProvider, { path, children: /* @__PURE__ */ jsxRuntime.jsx(
1613
+ CuiKitWrapper,
1614
+ {
1615
+ provider,
1616
+ props,
1617
+ nozzleProps: {
1618
+ nozzleIndex: index,
1619
+ nozzlePath: path,
1620
+ totalNozzles,
1621
+ isFirstNozzle: index === 0,
1622
+ isLastNozzle: index === totalNozzles - 1
1623
+ },
1624
+ children
1625
+ }
1626
+ ) }, path))) || [];
1627
+ return nozzles;
1628
+ }
1629
+ function CuiKit({
1630
+ provider,
1631
+ props
1632
+ }) {
1633
+ return ({ children }) => provider ? /* @__PURE__ */ jsxRuntime.jsx(DeviceAssemblyProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
1634
+ DispenseView,
1635
+ {
1636
+ provider,
1637
+ props,
1638
+ children
1639
+ }
1640
+ ) }) : null;
1641
+ }
1642
+ function initializeCuiKit(props) {
1643
+ const [useCuiKitContext, DispenseKitProvider] = createDispenseKitContext();
1644
+ return [
1645
+ useCuiKitContext,
1646
+ CuiKit({ provider: DispenseKitProvider, props })
1647
+ ];
1648
+ }
1649
+ const Holder = React.createContext(void 0);
1650
+ const HolderProvider = ({ children, id }) => {
1651
+ const { model, ready } = useHolder(id || "");
1652
+ const value = React.useMemo(() => {
1653
+ if (ready && model) {
1654
+ return { model };
1655
+ }
1656
+ return {};
1657
+ }, [ready, model]);
1658
+ return /* @__PURE__ */ jsxRuntime.jsx(Holder.Provider, { value, children });
1659
+ };
1660
+ const useHolderContext = () => {
1661
+ const context = React.useContext(Holder);
1662
+ if (!context) {
1663
+ throw new Error("useHolderContext must be used within a HolderProvider");
1664
+ }
1665
+ return context;
1666
+ };
1667
+ const HolderContainer = React.createContext(
1668
+ void 0
1669
+ );
1670
+ const HolderContainerProvider = ({ children }) => {
1671
+ const { model, ready } = useHolderContainer();
1672
+ const value = React.useMemo(() => {
1673
+ if (ready && model) {
1674
+ return { model };
1675
+ }
1676
+ return {};
1677
+ }, [ready, model]);
1678
+ return /* @__PURE__ */ jsxRuntime.jsx(HolderContainer.Provider, { value, children });
1679
+ };
1680
+ const useHolderContainerContext = () => {
1681
+ const context = React.useContext(HolderContainer);
1682
+ if (!context) {
1683
+ throw new Error(
1684
+ "useHolderContainerContext must be used within a HolderContainerProvider"
1685
+ );
1686
+ }
1687
+ return context;
1688
+ };
1689
+ const Ingredient = React.createContext(void 0);
1690
+ const IngredientProvider = ({ children }) => {
1691
+ const { model, ready } = useIngredient();
1692
+ const value = React.useMemo(() => {
1693
+ if (ready && model) {
1694
+ return { model };
1695
+ }
1696
+ return {};
1697
+ }, [ready, model]);
1698
+ return /* @__PURE__ */ jsxRuntime.jsx(Ingredient.Provider, { value, children });
1699
+ };
1700
+ const useIngredientContext = () => {
1701
+ const context = React.useContext(Ingredient);
1702
+ if (!context) {
1703
+ throw new Error(
1704
+ "useIngredientContext must be used within a IngredientProvider"
1705
+ );
1706
+ }
1707
+ return context;
1708
+ };
1709
+ const IngredientContainer = React.createContext(
1710
+ void 0
1711
+ );
1712
+ const IngredientContainerProvider = ({ children }) => {
1713
+ const { model, ready } = useIngredientContainer();
1714
+ const value = React.useMemo(() => {
1715
+ if (ready && model) {
1716
+ return { model };
1717
+ }
1718
+ return {};
1719
+ }, [ready, model]);
1720
+ return /* @__PURE__ */ jsxRuntime.jsx(IngredientContainer.Provider, { value, children });
1721
+ };
1722
+ const useIngredientContainerContext = () => {
1723
+ const context = React.useContext(IngredientContainer);
1724
+ if (!context) {
1725
+ throw new Error(
1726
+ "useIngredientContainerContext must be used within a IngredientContainerProvider"
1727
+ );
1728
+ }
1729
+ return context;
1730
+ };
1731
+ const usePump = () => {
1732
+ const modelId = dispenseRegistrationManager.Pump.type;
1733
+ const result = kosUiSdk.useKosModel({
1734
+ modelId,
1735
+ modelType: dispenseRegistrationManager.Pump.type,
1736
+ options: {}
1737
+ });
1738
+ return result;
1739
+ };
1740
+ const Pump = React.createContext(void 0);
1741
+ const PumpProvider = ({ children }) => {
1742
+ const { model, ready } = usePump();
1743
+ const value = React.useMemo(() => {
1744
+ if (ready && model) {
1745
+ return { model };
1746
+ }
1747
+ return {};
1748
+ }, [ready, model]);
1749
+ return /* @__PURE__ */ jsxRuntime.jsx(Pump.Provider, { value, children });
1750
+ };
1751
+ const usePumpContext = () => {
1752
+ const context = React.useContext(Pump);
1753
+ if (!context) {
1754
+ throw new Error("usePumpContext must be used within a PumpProvider");
1755
+ }
1756
+ return context;
1757
+ };
1758
+ exports.AssemblyProvider = AssemblyProvider;
1759
+ exports.AvailabilityProvider = AvailabilityProvider;
1760
+ exports.BoardContainerProvider = BoardContainerProvider;
1761
+ exports.BoardProvider = BoardProvider;
1762
+ exports.CuiKit = CuiKit;
1763
+ exports.CuiKitWrapper = CuiKitWrapper;
1764
+ exports.DISPENSE_GROUP_BEVERAGE = DISPENSE_GROUP_BEVERAGE;
1765
+ exports.DISPENSE_GROUP_BRAND = DISPENSE_GROUP_BRAND;
1766
+ exports.DISPENSE_GROUP_FLAVOR = DISPENSE_GROUP_FLAVOR;
1767
+ exports.DeviceAssemblyProvider = DeviceAssemblyProvider;
1768
+ exports.HoldToPourIntentStrategy = HoldToPourIntentStrategy;
1769
+ exports.HoldToPourStrategy = HoldToPourStrategy;
1770
+ exports.HolderContainerProvider = HolderContainerProvider;
1771
+ exports.HolderProvider = HolderProvider;
1772
+ exports.IngredientContainerProvider = IngredientContainerProvider;
1773
+ exports.IngredientProvider = IngredientProvider;
1774
+ exports.NozzleProvider = NozzleProvider;
1775
+ exports.PourContext = PourContext;
1776
+ exports.PumpProvider = PumpProvider;
1777
+ exports.TapOrHoldIntentStrategy = TapOrHoldIntentStrategy;
1778
+ exports.TapToPourIntentStrategy = TapToPourIntentStrategy;
1779
+ exports.TapToPourStrategy = TapToPourStrategy;
1780
+ exports.initializeCuiKit = initializeCuiKit;
1781
+ exports.useAssembly = useAssembly;
1782
+ exports.useAssemblyContext = useAssemblyContext;
1783
+ exports.useAvailability = useAvailability;
1784
+ exports.useAvailabilityContext = useAvailabilityContext;
1785
+ exports.useBeverages = useBeverages;
1786
+ exports.useBoard = useBoard;
1787
+ exports.useBoardContainer = useBoardContainer;
1788
+ exports.useBoardContainerContext = useBoardContainerContext;
1789
+ exports.useBoardContext = useBoardContext;
1790
+ exports.useBrands = useBrands;
1791
+ exports.useCuiKit = useCuiKit;
1792
+ exports.useCuiKitTimers = useCuiKitTimers;
1793
+ exports.useDefaultCuiKitLifecycle = useDefaultCuiKitLifecycle;
1794
+ exports.useDeviceAssembly = useDeviceAssembly;
1795
+ exports.useDeviceAssemblyContext = useDeviceAssemblyContext;
1796
+ exports.useDispenseLifecycle = useDispenseLifecycle;
1797
+ exports.useFlavors = useFlavors;
1798
+ exports.useGenericPour = useGenericPour;
1799
+ exports.useHolder = useHolder;
1800
+ exports.useHolderContainer = useHolderContainer;
1801
+ exports.useHolderContainerContext = useHolderContainerContext;
1802
+ exports.useHolderContext = useHolderContext;
1803
+ exports.useIngredient = useIngredient;
1804
+ exports.useIngredientContainer = useIngredientContainer;
1805
+ exports.useIngredientContainerContext = useIngredientContainerContext;
1806
+ exports.useIngredientContext = useIngredientContext;
1807
+ exports.useIngredientPour = useIngredientPour;
1808
+ exports.useNozzle = useNozzle;
1809
+ exports.useNozzleContext = useNozzleContext;
1810
+ exports.useNozzlePour = useNozzlePour;
1811
+ exports.usePourTarget = usePourTarget;
1812
+ exports.usePumpContext = usePumpContext;
1813
+ exports.withAssembly = withAssembly;
1814
+ exports.withBeverage = withBeverage;
1815
+ exports.withBoard = withBoard;
1816
+ exports.withBoardContainer = withBoardContainer;
1817
+ exports.withDeviceAssembly = withDeviceAssembly;
1818
+ exports.withGenericPour = withGenericPour;
1819
+ exports.withHolder = withHolder;
1820
+ exports.withHolderContainer = withHolderContainer;
1821
+ exports.withIngredient = withIngredient;
1822
+ exports.withIngredientContainer = withIngredientContainer;
1823
+ exports.withNozzle = withNozzle;
1824
+ //# sourceMappingURL=pump-provider-D4Ed_gH6.cjs.map