@wix/headless-restaurants-olo 0.0.61 → 0.0.63

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.
@@ -116,6 +116,13 @@ export interface SpecialRequestProps {
116
116
  value: string;
117
117
  onChange: (value: string) => void;
118
118
  allowSpecialRequest: boolean;
119
+ /**
120
+ * Owner-configured placeholder text for the special-request textarea.
121
+ * `undefined` → consumers should use their default placeholder.
122
+ * `""` → consumers should render NO placeholder.
123
+ * `"..."` → consumers should use the string as-is.
124
+ */
125
+ specialRequestInstructions?: string;
119
126
  }>;
120
127
  /** Placeholder text for the textarea */
121
128
  placeholder?: string;
@@ -266,12 +266,13 @@ exports.Quantity.displayName = 'Quantity';
266
266
  * ```
267
267
  */
268
268
  exports.SpecialRequest = react_1.default.forwardRef(({ className, labelClassName, placeholder = 'Any special requests or dietary restrictions?', maxLength = 200, rows = 3, label = 'Special Requests', asChild, children, ...props }, ref) => {
269
- return ((0, jsx_runtime_1.jsx)(CoreItemDetails.SpecialRequest, { children: ({ value, onChange, allowSpecialRequest, }) => {
269
+ return ((0, jsx_runtime_1.jsx)(CoreItemDetails.SpecialRequest, { children: ({ value, onChange, allowSpecialRequest, specialRequestInstructions, }) => {
270
270
  return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, onChange: onChange, "data-testid": TestIds.itemSpecialRequest, customElement: children, customElementProps: {
271
271
  label,
272
272
  value,
273
273
  onChange,
274
274
  allowSpecialRequest,
275
+ specialRequestInstructions,
275
276
  }, content: value, ...props, children: allowSpecialRequest && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [label && (0, jsx_runtime_1.jsx)("label", { className: labelClassName, children: label }), (0, jsx_runtime_1.jsx)("textarea", { value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, maxLength: maxLength, rows: rows, className: className, children: value })] })) }));
276
277
  } }));
277
278
  });
@@ -15,6 +15,7 @@ interface ItemDetailsSpecialRequestProps {
15
15
  value: string;
16
16
  onChange: (value: string) => void;
17
17
  allowSpecialRequest: boolean;
18
+ specialRequestInstructions?: string;
18
19
  }) => React.ReactNode;
19
20
  }
20
21
  export declare const SpecialRequest: React.FC<ItemDetailsSpecialRequestProps>;
@@ -16,6 +16,7 @@ exports.Root = Root;
16
16
  const SpecialRequest = ({ children, }) => {
17
17
  const service = (0, services_manager_react_1.useService)(item_details_service_js_1.ItemServiceDefinition);
18
18
  const allowSpecialRequest = service.allowSpecialRequest;
19
+ const specialRequestInstructions = service.specialRequestInstructions;
19
20
  const initialSpecialRequest = service.specialRequest?.get?.() ?? '';
20
21
  const [value, setValue] = (0, react_1.useState)(initialSpecialRequest);
21
22
  const onChange = (newValue) => {
@@ -28,6 +29,7 @@ const SpecialRequest = ({ children, }) => {
28
29
  value,
29
30
  onChange,
30
31
  allowSpecialRequest,
32
+ specialRequestInstructions,
31
33
  // placeholder: 'Any special requests or dietary restrictions?',
32
34
  // maxLength: 200
33
35
  });
@@ -16,6 +16,7 @@ export interface ItemServiceAPI {
16
16
  quantity: Signal<number>;
17
17
  specialRequest: Signal<string>;
18
18
  allowSpecialRequest: boolean;
19
+ specialRequestInstructions?: string;
19
20
  lineItem: ReadOnlySignal<LineItem>;
20
21
  onHandleAddToCart: (onClick: (lineItem: LineItem) => void) => void;
21
22
  buttonState: ReadOnlySignal<AddToCartButtonState | undefined>;
@@ -69,6 +70,7 @@ export interface ItemServiceConfig {
69
70
  operationId?: string;
70
71
  availabilityStatus?: AvailabilityStatus;
71
72
  allowSpecialRequest?: boolean;
73
+ specialRequestInstructions?: string;
72
74
  editItemMode?: boolean;
73
75
  editingItemValues?: {
74
76
  quantity?: number;
@@ -55,6 +55,7 @@ exports.ItemService = services_definitions_1.implementService.withConfig()(expor
55
55
  weeklyAvailabilitySummary: undefined,
56
56
  };
57
57
  const allowSpecialRequest = config.allowSpecialRequest ?? true;
58
+ const specialRequestInstructions = config.specialRequestInstructions;
58
59
  const signalsService = getService(signals_1.SignalsServiceDefinition);
59
60
  const oloSettingsService = getService(olo_settings_service_js_1.OLOSettingsServiceDefinition);
60
61
  const availabilityStatus = signalsService.signal(config.availabilityStatus ?? common_types_js_1.AvailabilityStatus.AVAILABLE);
@@ -221,6 +222,7 @@ exports.ItemService = services_definitions_1.implementService.withConfig()(expor
221
222
  price,
222
223
  futureAvailability,
223
224
  allowSpecialRequest,
225
+ specialRequestInstructions,
224
226
  };
225
227
  });
226
228
  /**
@@ -11,6 +11,7 @@ export declare const getFirstPreSelectedModifier: (modifiers: EnhancedModifier[]
11
11
  export declare const getPreSelectedModifiers: (modifiers: EnhancedModifier[]) => string[];
12
12
  export declare const convertModifierToFormModifier: (modifier: EnhancedModifier, index: number) => {
13
13
  _id: string;
14
+ modifierId: string | null | undefined;
14
15
  revision?: string | null;
15
16
  _createdDate?: Date | null;
16
17
  _updatedDate?: Date | null;
@@ -40,6 +41,22 @@ export declare const getModifierGroupErrors: (selectedModifiers: Record<string,
40
41
  hasError: boolean;
41
42
  };
42
43
  export declare const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock: (modifierGroups: EnhancedModifierGroup[]) => boolean;
44
+ export declare const findModifierByFormId: (modifierGroup: EnhancedModifierGroup | undefined, selectedModifierId: string) => {
45
+ _id: string;
46
+ modifierId: string | null | undefined;
47
+ revision?: string | null;
48
+ _createdDate?: Date | null;
49
+ _updatedDate?: Date | null;
50
+ name?: string | null;
51
+ extendedFields?: import("@wix/auto_sdk_restaurants_item-modifiers").ExtendedFields;
52
+ inStock?: boolean | null;
53
+ businessLocationIds?: string[];
54
+ additionalChargeInfo?: {
55
+ additionalCharge?: string;
56
+ formattedAdditionalCharge?: string;
57
+ };
58
+ preSelected?: boolean;
59
+ } | undefined;
43
60
  export declare const getLineItemModifiers: (selectedModifiers: Record<string, Array<string>>, modifierGroups: EnhancedModifierGroup[], formatCurrency: (price?: number) => string) => {
44
61
  id: string;
45
62
  modifiers: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAvailabilityText = exports.calculateItemPrice = exports.getSelectedVariantPrice = exports.getSelectedModifierPrices = exports.getPriceVariantOptions = exports.getLineItemModifiers = exports.getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = exports.getModifierGroupErrors = exports.checkModifiersValidation = exports.getRuleTypeMapValue = exports.hasToChooseBetweenXAndY = exports.chooseUpToX = exports.hasToChooseAtLeastX = exports.hasToChooseAtLeastOne = exports.hasToChooseX = exports.hasToChooseOne = exports.canChooseOne = exports.hasNoLimit = exports.getModifierGroupRuleType = exports.convertModifierToFormModifier = exports.getPreSelectedModifiers = exports.getFirstPreSelectedModifier = exports.isSingleSelectRule = exports.getModifiersInitState = void 0;
3
+ exports.getAvailabilityText = exports.calculateItemPrice = exports.getSelectedVariantPrice = exports.getSelectedModifierPrices = exports.getPriceVariantOptions = exports.getLineItemModifiers = exports.findModifierByFormId = exports.getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = exports.getModifierGroupErrors = exports.checkModifiersValidation = exports.getRuleTypeMapValue = exports.hasToChooseBetweenXAndY = exports.chooseUpToX = exports.hasToChooseAtLeastX = exports.hasToChooseAtLeastOne = exports.hasToChooseX = exports.hasToChooseOne = exports.canChooseOne = exports.hasNoLimit = exports.getModifierGroupRuleType = exports.convertModifierToFormModifier = exports.getPreSelectedModifiers = exports.getFirstPreSelectedModifier = exports.isSingleSelectRule = exports.getModifiersInitState = void 0;
4
4
  const common_types_js_1 = require("./common-types.js");
5
5
  const getModifiersInitState = (modifierGroups, editingItemMode, editItemSelectedModifiers) => {
6
6
  const initialSelectedModifiers = {};
@@ -42,9 +42,13 @@ const getPreSelectedModifiers = (modifiers) => modifiers.reduce((acc, modifier)
42
42
  }, []);
43
43
  exports.getPreSelectedModifiers = getPreSelectedModifiers;
44
44
  const convertModifierToFormModifier = (modifier, index) => {
45
+ // Give each modifier a unique form id so duplicate-id modifiers stay
46
+ // distinct in the UI/selection state, while keeping the original id in
47
+ // `modifierId` so it can be read back without parsing the form id.
45
48
  return {
46
49
  ...modifier,
47
50
  _id: `${modifier._id}~${index}`,
51
+ modifierId: modifier._id,
48
52
  };
49
53
  };
50
54
  exports.convertModifierToFormModifier = convertModifierToFormModifier;
@@ -198,6 +202,17 @@ const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = (modifierGroups)
198
202
  return isModifierGroupMandatory && !areMinimumRequiredModifiersInStock;
199
203
  });
200
204
  exports.getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = getAreNotEnoughModifiersOfMandatoryModifierGroupInStock;
205
+ // Resolve the selected modifier from a group. Selection state holds unique
206
+ // form ids (`${_id}~${index}`, see convertModifierToFormModifier), so we match
207
+ // the converted form modifiers by their unique `_id` — this keeps duplicate-id
208
+ // modifiers distinct and avoids parsing the id. Falls back to matching the
209
+ // original `modifierId` for edit-mode selections that are restored as base ids.
210
+ const findModifierByFormId = (modifierGroup, selectedModifierId) => {
211
+ const formModifiers = modifierGroup?.modifiers.map(exports.convertModifierToFormModifier);
212
+ return (formModifiers?.find((mod) => mod._id === selectedModifierId) ??
213
+ formModifiers?.find((mod) => mod.modifierId === selectedModifierId));
214
+ };
215
+ exports.findModifierByFormId = findModifierByFormId;
201
216
  const getLineItemModifiers = (selectedModifiers, modifierGroups, formatCurrency) => {
202
217
  const modifierGroupsOptions = modifierGroups
203
218
  .map((modifierGroup) => {
@@ -207,13 +222,12 @@ const getLineItemModifiers = (selectedModifiers, modifierGroups, formatCurrency)
207
222
  }
208
223
  const modifiers = selectedModifierIds
209
224
  .map((modifierIdWithIndex) => {
210
- const baseModifierId = modifierIdWithIndex.split('~')[0];
211
- const modifier = modifierGroup.modifiers.find((mod) => mod._id === baseModifierId);
225
+ const modifier = (0, exports.findModifierByFormId)(modifierGroup, modifierIdWithIndex);
212
226
  if (!modifier)
213
227
  return null;
214
228
  const price = Number(modifier?.additionalChargeInfo?.additionalCharge ?? 0);
215
229
  return {
216
- id: modifier._id ?? '',
230
+ id: modifier.modifierId ?? '',
217
231
  price: modifier?.additionalChargeInfo?.additionalCharge,
218
232
  formattedPrice: price > 0 ? formatCurrency(price) : undefined,
219
233
  };
@@ -248,11 +262,9 @@ const getPriceVariantOptions = (selectedPriceVariant, formatCurrency) => {
248
262
  exports.getPriceVariantOptions = getPriceVariantOptions;
249
263
  const getSelectedModifierPrices = (selectedModifiers, modifierGroups) => {
250
264
  return Object.entries(selectedModifiers).reduce((total, [modifierGroupId, modifierIds]) => {
265
+ const group = modifierGroups.find((g) => g._id === modifierGroupId);
251
266
  const groupTotal = modifierIds.reduce((groupSum, modifierId) => {
252
- const baseModifierId = modifierId.split('~')[0];
253
- const modifier = modifierGroups
254
- .find((group) => group._id === modifierGroupId)
255
- ?.modifiers.find((mod) => mod._id === baseModifierId);
267
+ const modifier = (0, exports.findModifierByFormId)(group, modifierId);
256
268
  return (groupSum +
257
269
  Number(modifier?.additionalChargeInfo?.additionalCharge ?? 0));
258
270
  }, 0);
@@ -116,6 +116,13 @@ export interface SpecialRequestProps {
116
116
  value: string;
117
117
  onChange: (value: string) => void;
118
118
  allowSpecialRequest: boolean;
119
+ /**
120
+ * Owner-configured placeholder text for the special-request textarea.
121
+ * `undefined` → consumers should use their default placeholder.
122
+ * `""` → consumers should render NO placeholder.
123
+ * `"..."` → consumers should use the string as-is.
124
+ */
125
+ specialRequestInstructions?: string;
119
126
  }>;
120
127
  /** Placeholder text for the textarea */
121
128
  placeholder?: string;
@@ -225,12 +225,13 @@ Quantity.displayName = 'Quantity';
225
225
  * ```
226
226
  */
227
227
  export const SpecialRequest = React.forwardRef(({ className, labelClassName, placeholder = 'Any special requests or dietary restrictions?', maxLength = 200, rows = 3, label = 'Special Requests', asChild, children, ...props }, ref) => {
228
- return (_jsx(CoreItemDetails.SpecialRequest, { children: ({ value, onChange, allowSpecialRequest, }) => {
228
+ return (_jsx(CoreItemDetails.SpecialRequest, { children: ({ value, onChange, allowSpecialRequest, specialRequestInstructions, }) => {
229
229
  return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, onChange: onChange, "data-testid": TestIds.itemSpecialRequest, customElement: children, customElementProps: {
230
230
  label,
231
231
  value,
232
232
  onChange,
233
233
  allowSpecialRequest,
234
+ specialRequestInstructions,
234
235
  }, content: value, ...props, children: allowSpecialRequest && (_jsxs(_Fragment, { children: [label && _jsx("label", { className: labelClassName, children: label }), _jsx("textarea", { value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, maxLength: maxLength, rows: rows, className: className, children: value })] })) }));
235
236
  } }));
236
237
  });
@@ -15,6 +15,7 @@ interface ItemDetailsSpecialRequestProps {
15
15
  value: string;
16
16
  onChange: (value: string) => void;
17
17
  allowSpecialRequest: boolean;
18
+ specialRequestInstructions?: string;
18
19
  }) => React.ReactNode;
19
20
  }
20
21
  export declare const SpecialRequest: React.FC<ItemDetailsSpecialRequestProps>;
@@ -12,6 +12,7 @@ export const Root = ({ children, itemDetailsServiceConfig, }) => {
12
12
  export const SpecialRequest = ({ children, }) => {
13
13
  const service = useService(ItemServiceDefinition);
14
14
  const allowSpecialRequest = service.allowSpecialRequest;
15
+ const specialRequestInstructions = service.specialRequestInstructions;
15
16
  const initialSpecialRequest = service.specialRequest?.get?.() ?? '';
16
17
  const [value, setValue] = useState(initialSpecialRequest);
17
18
  const onChange = (newValue) => {
@@ -24,6 +25,7 @@ export const SpecialRequest = ({ children, }) => {
24
25
  value,
25
26
  onChange,
26
27
  allowSpecialRequest,
28
+ specialRequestInstructions,
27
29
  // placeholder: 'Any special requests or dietary restrictions?',
28
30
  // maxLength: 200
29
31
  });
@@ -16,6 +16,7 @@ export interface ItemServiceAPI {
16
16
  quantity: Signal<number>;
17
17
  specialRequest: Signal<string>;
18
18
  allowSpecialRequest: boolean;
19
+ specialRequestInstructions?: string;
19
20
  lineItem: ReadOnlySignal<LineItem>;
20
21
  onHandleAddToCart: (onClick: (lineItem: LineItem) => void) => void;
21
22
  buttonState: ReadOnlySignal<AddToCartButtonState | undefined>;
@@ -69,6 +70,7 @@ export interface ItemServiceConfig {
69
70
  operationId?: string;
70
71
  availabilityStatus?: AvailabilityStatus;
71
72
  allowSpecialRequest?: boolean;
73
+ specialRequestInstructions?: string;
72
74
  editItemMode?: boolean;
73
75
  editingItemValues?: {
74
76
  quantity?: number;
@@ -51,6 +51,7 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
51
51
  weeklyAvailabilitySummary: undefined,
52
52
  };
53
53
  const allowSpecialRequest = config.allowSpecialRequest ?? true;
54
+ const specialRequestInstructions = config.specialRequestInstructions;
54
55
  const signalsService = getService(SignalsServiceDefinition);
55
56
  const oloSettingsService = getService(OLOSettingsServiceDefinition);
56
57
  const availabilityStatus = signalsService.signal(config.availabilityStatus ?? AvailabilityStatus.AVAILABLE);
@@ -217,6 +218,7 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
217
218
  price,
218
219
  futureAvailability,
219
220
  allowSpecialRequest,
221
+ specialRequestInstructions,
220
222
  };
221
223
  });
222
224
  /**
@@ -11,6 +11,7 @@ export declare const getFirstPreSelectedModifier: (modifiers: EnhancedModifier[]
11
11
  export declare const getPreSelectedModifiers: (modifiers: EnhancedModifier[]) => string[];
12
12
  export declare const convertModifierToFormModifier: (modifier: EnhancedModifier, index: number) => {
13
13
  _id: string;
14
+ modifierId: string | null | undefined;
14
15
  revision?: string | null;
15
16
  _createdDate?: Date | null;
16
17
  _updatedDate?: Date | null;
@@ -40,6 +41,22 @@ export declare const getModifierGroupErrors: (selectedModifiers: Record<string,
40
41
  hasError: boolean;
41
42
  };
42
43
  export declare const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock: (modifierGroups: EnhancedModifierGroup[]) => boolean;
44
+ export declare const findModifierByFormId: (modifierGroup: EnhancedModifierGroup | undefined, selectedModifierId: string) => {
45
+ _id: string;
46
+ modifierId: string | null | undefined;
47
+ revision?: string | null;
48
+ _createdDate?: Date | null;
49
+ _updatedDate?: Date | null;
50
+ name?: string | null;
51
+ extendedFields?: import("@wix/auto_sdk_restaurants_item-modifiers").ExtendedFields;
52
+ inStock?: boolean | null;
53
+ businessLocationIds?: string[];
54
+ additionalChargeInfo?: {
55
+ additionalCharge?: string;
56
+ formattedAdditionalCharge?: string;
57
+ };
58
+ preSelected?: boolean;
59
+ } | undefined;
43
60
  export declare const getLineItemModifiers: (selectedModifiers: Record<string, Array<string>>, modifierGroups: EnhancedModifierGroup[], formatCurrency: (price?: number) => string) => {
44
61
  id: string;
45
62
  modifiers: {
@@ -35,9 +35,13 @@ export const getPreSelectedModifiers = (modifiers) => modifiers.reduce((acc, mod
35
35
  return acc;
36
36
  }, []);
37
37
  export const convertModifierToFormModifier = (modifier, index) => {
38
+ // Give each modifier a unique form id so duplicate-id modifiers stay
39
+ // distinct in the UI/selection state, while keeping the original id in
40
+ // `modifierId` so it can be read back without parsing the form id.
38
41
  return {
39
42
  ...modifier,
40
43
  _id: `${modifier._id}~${index}`,
44
+ modifierId: modifier._id,
41
45
  };
42
46
  };
43
47
  export const getModifierGroupRuleType = (modifierGroupRule) => {
@@ -177,6 +181,16 @@ export const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = (modifier
177
181
  const areMinimumRequiredModifiersInStock = inStockModifiers.length >= minimumRequiredModifiers;
178
182
  return isModifierGroupMandatory && !areMinimumRequiredModifiersInStock;
179
183
  });
184
+ // Resolve the selected modifier from a group. Selection state holds unique
185
+ // form ids (`${_id}~${index}`, see convertModifierToFormModifier), so we match
186
+ // the converted form modifiers by their unique `_id` — this keeps duplicate-id
187
+ // modifiers distinct and avoids parsing the id. Falls back to matching the
188
+ // original `modifierId` for edit-mode selections that are restored as base ids.
189
+ export const findModifierByFormId = (modifierGroup, selectedModifierId) => {
190
+ const formModifiers = modifierGroup?.modifiers.map(convertModifierToFormModifier);
191
+ return (formModifiers?.find((mod) => mod._id === selectedModifierId) ??
192
+ formModifiers?.find((mod) => mod.modifierId === selectedModifierId));
193
+ };
180
194
  export const getLineItemModifiers = (selectedModifiers, modifierGroups, formatCurrency) => {
181
195
  const modifierGroupsOptions = modifierGroups
182
196
  .map((modifierGroup) => {
@@ -186,13 +200,12 @@ export const getLineItemModifiers = (selectedModifiers, modifierGroups, formatCu
186
200
  }
187
201
  const modifiers = selectedModifierIds
188
202
  .map((modifierIdWithIndex) => {
189
- const baseModifierId = modifierIdWithIndex.split('~')[0];
190
- const modifier = modifierGroup.modifiers.find((mod) => mod._id === baseModifierId);
203
+ const modifier = findModifierByFormId(modifierGroup, modifierIdWithIndex);
191
204
  if (!modifier)
192
205
  return null;
193
206
  const price = Number(modifier?.additionalChargeInfo?.additionalCharge ?? 0);
194
207
  return {
195
- id: modifier._id ?? '',
208
+ id: modifier.modifierId ?? '',
196
209
  price: modifier?.additionalChargeInfo?.additionalCharge,
197
210
  formattedPrice: price > 0 ? formatCurrency(price) : undefined,
198
211
  };
@@ -225,11 +238,9 @@ export const getPriceVariantOptions = (selectedPriceVariant, formatCurrency) =>
225
238
  };
226
239
  export const getSelectedModifierPrices = (selectedModifiers, modifierGroups) => {
227
240
  return Object.entries(selectedModifiers).reduce((total, [modifierGroupId, modifierIds]) => {
241
+ const group = modifierGroups.find((g) => g._id === modifierGroupId);
228
242
  const groupTotal = modifierIds.reduce((groupSum, modifierId) => {
229
- const baseModifierId = modifierId.split('~')[0];
230
- const modifier = modifierGroups
231
- .find((group) => group._id === modifierGroupId)
232
- ?.modifiers.find((mod) => mod._id === baseModifierId);
243
+ const modifier = findModifierByFormId(group, modifierId);
233
244
  return (groupSum +
234
245
  Number(modifier?.additionalChargeInfo?.additionalCharge ?? 0));
235
246
  }, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-restaurants-olo",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -81,5 +81,5 @@
81
81
  "groupId": "com.wixpress.headless-components"
82
82
  }
83
83
  },
84
- "falconPackageHash": "4830d00db46708a89c356f92871d09da486b92a017c85d5fd113cd6f"
84
+ "falconPackageHash": "7b2dc448774c9f7997e48a6683f7290b40c6ab6d0ced934655719da7"
85
85
  }