@tmlmt/cooklang-parser 3.0.0-alpha.16 → 3.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +81 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +81 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -114,6 +114,11 @@ declare class Recipe {
|
|
|
114
114
|
* Used for giving ID numbers to items during parsing.
|
|
115
115
|
*/
|
|
116
116
|
private static itemCounts;
|
|
117
|
+
/**
|
|
118
|
+
* External storage for subgroup index tracking during parsing.
|
|
119
|
+
* Maps groupKey → subgroupKey → index within the subgroups array.
|
|
120
|
+
*/
|
|
121
|
+
private static subgroupIndices;
|
|
117
122
|
/**
|
|
118
123
|
* Gets the current item count for this recipe.
|
|
119
124
|
*/
|
|
@@ -613,6 +618,12 @@ interface IngredientItem {
|
|
|
613
618
|
* `@|group|...` syntax), they represent a single logical choice.
|
|
614
619
|
*/
|
|
615
620
|
group?: string;
|
|
621
|
+
/**
|
|
622
|
+
* An optional subgroup identifier for binding multiple ingredients together
|
|
623
|
+
* within a group. Ingredients sharing the same `group` and `subgroup` are
|
|
624
|
+
* selected together as a unit (e.g., from `@|group/1|...` syntax).
|
|
625
|
+
*/
|
|
626
|
+
subgroup?: string;
|
|
616
627
|
}
|
|
617
628
|
/**
|
|
618
629
|
* Represents the choices one can make in a recipe
|
|
@@ -626,9 +637,13 @@ interface RecipeAlternatives {
|
|
|
626
637
|
ingredientItems: Map<string, IngredientAlternative[]>;
|
|
627
638
|
/** Map of choices that can be made for Grouped Ingredient StepItem's
|
|
628
639
|
* - Keys are the Group IDs (e.g. "eggs" for `@|eggs|...`)
|
|
629
|
-
* - Values are arrays of
|
|
640
|
+
* - Values are arrays of subgroups, where each subgroup is an array of
|
|
641
|
+
* bound IngredientAlternative objects that are selected together.
|
|
642
|
+
* Items sharing the same subgroup key (e.g., `@|group/1|...`) are
|
|
643
|
+
* in the same inner array. Items without a subgroup key each form
|
|
644
|
+
* their own single-element subgroup.
|
|
630
645
|
*/
|
|
631
|
-
ingredientGroups: Map<string, IngredientAlternative[]>;
|
|
646
|
+
ingredientGroups: Map<string, IngredientAlternative[][]>;
|
|
632
647
|
}
|
|
633
648
|
/**
|
|
634
649
|
* Represents the choices to apply when computing ingredient quantities.
|
package/dist/index.d.ts
CHANGED
|
@@ -114,6 +114,11 @@ declare class Recipe {
|
|
|
114
114
|
* Used for giving ID numbers to items during parsing.
|
|
115
115
|
*/
|
|
116
116
|
private static itemCounts;
|
|
117
|
+
/**
|
|
118
|
+
* External storage for subgroup index tracking during parsing.
|
|
119
|
+
* Maps groupKey → subgroupKey → index within the subgroups array.
|
|
120
|
+
*/
|
|
121
|
+
private static subgroupIndices;
|
|
117
122
|
/**
|
|
118
123
|
* Gets the current item count for this recipe.
|
|
119
124
|
*/
|
|
@@ -613,6 +618,12 @@ interface IngredientItem {
|
|
|
613
618
|
* `@|group|...` syntax), they represent a single logical choice.
|
|
614
619
|
*/
|
|
615
620
|
group?: string;
|
|
621
|
+
/**
|
|
622
|
+
* An optional subgroup identifier for binding multiple ingredients together
|
|
623
|
+
* within a group. Ingredients sharing the same `group` and `subgroup` are
|
|
624
|
+
* selected together as a unit (e.g., from `@|group/1|...` syntax).
|
|
625
|
+
*/
|
|
626
|
+
subgroup?: string;
|
|
616
627
|
}
|
|
617
628
|
/**
|
|
618
629
|
* Represents the choices one can make in a recipe
|
|
@@ -626,9 +637,13 @@ interface RecipeAlternatives {
|
|
|
626
637
|
ingredientItems: Map<string, IngredientAlternative[]>;
|
|
627
638
|
/** Map of choices that can be made for Grouped Ingredient StepItem's
|
|
628
639
|
* - Keys are the Group IDs (e.g. "eggs" for `@|eggs|...`)
|
|
629
|
-
* - Values are arrays of
|
|
640
|
+
* - Values are arrays of subgroups, where each subgroup is an array of
|
|
641
|
+
* bound IngredientAlternative objects that are selected together.
|
|
642
|
+
* Items sharing the same subgroup key (e.g., `@|group/1|...`) are
|
|
643
|
+
* in the same inner array. Items without a subgroup key each form
|
|
644
|
+
* their own single-element subgroup.
|
|
630
645
|
*/
|
|
631
|
-
ingredientGroups: Map<string, IngredientAlternative[]>;
|
|
646
|
+
ingredientGroups: Map<string, IngredientAlternative[][]>;
|
|
632
647
|
}
|
|
633
648
|
/**
|
|
634
649
|
* Represents the choices to apply when computing ingredient quantities.
|
package/dist/index.js
CHANGED
|
@@ -277,7 +277,7 @@ var nonWordCharStrict = "\\s@#~\\[\\]{(,;:!?|";
|
|
|
277
277
|
var ingredientWithAlternativeRegex = d().literal("@").startNamedGroup("ingredientModifiers").anyOf("@\\-&?").zeroOrMore().endGroup().optional().startNamedGroup("ingredientRecipeAnchor").literal("./").endGroup().optional().startGroup().startGroup().startNamedGroup("mIngredientName").notAnyOf(nonWordChar).oneOrMore().startGroup().whitespace().oneOrMore().notAnyOf(nonWordChar).oneOrMore().endGroup().oneOrMore().endGroup().positiveLookahead("\\s*(?:\\{[^\\}]*\\}|\\([^)]*\\))").endGroup().or().startNamedGroup("sIngredientName").notAnyOf(nonWordChar).zeroOrMore().notAnyOf("\\." + nonWordChar).endGroup().endGroup().startGroup().literal("{").startNamedGroup("ingredientQuantityModifier").literal("=").exactly(1).endGroup().optional().startNamedGroup("ingredientQuantity").startGroup().notAnyOf("}|%").oneOrMore().endGroup().optional().startGroup().literal("%").notAnyOf("|}").oneOrMore().lazy().endGroup().optional().startGroup().literal("|").notAnyOf("}").oneOrMore().lazy().endGroup().zeroOrMore().endGroup().literal("}").endGroup().optional().startGroup().literal("(").startNamedGroup("ingredientPreparation").notAnyOf(")").oneOrMore().lazy().endGroup().literal(")").endGroup().optional().startGroup().literal("[").startNamedGroup("ingredientNote").notAnyOf("\\]").oneOrMore().lazy().endGroup().literal("]").endGroup().optional().startNamedGroup("ingredientAlternative").startGroup().literal("|").startGroup().anyOf("@\\-&?").zeroOrMore().endGroup().optional().startGroup().literal("./").endGroup().optional().startGroup().startGroup().startGroup().notAnyOf(nonWordChar).oneOrMore().startGroup().whitespace().oneOrMore().notAnyOf(nonWordChar).oneOrMore().endGroup().oneOrMore().endGroup().positiveLookahead("\\s*(?:\\{[^\\}]*\\}|\\([^)]*\\))").endGroup().or().startGroup().notAnyOf(nonWordChar).oneOrMore().endGroup().endGroup().startGroup().literal("{").startGroup().literal("=").exactly(1).endGroup().optional().startGroup().notAnyOf("}%").oneOrMore().endGroup().optional().startGroup().literal("%").startGroup().notAnyOf("}").oneOrMore().lazy().endGroup().endGroup().optional().literal("}").endGroup().optional().startGroup().literal("(").startGroup().notAnyOf(")").oneOrMore().lazy().endGroup().literal(")").endGroup().optional().startGroup().literal("[").startGroup().notAnyOf("\\]").oneOrMore().lazy().endGroup().literal("]").endGroup().optional().endGroup().zeroOrMore().endGroup().toRegExp();
|
|
278
278
|
var inlineIngredientAlternativesRegex = new RegExp("\\|" + ingredientWithAlternativeRegex.source.slice(1));
|
|
279
279
|
var quantityAlternativeRegex = d().startNamedGroup("quantity").notAnyOf("}|%").oneOrMore().endGroup().optional().startGroup().literal("%").startNamedGroup("unit").notAnyOf("|}").oneOrMore().endGroup().endGroup().optional().startGroup().literal("|").startNamedGroup("alternative").startGroup().notAnyOf("}").oneOrMore().endGroup().zeroOrMore().endGroup().endGroup().optional().toRegExp();
|
|
280
|
-
var ingredientWithGroupKeyRegex = d().literal("@|").startNamedGroup("gIngredientGroupKey").notAnyOf(nonWordCharStrict).oneOrMore().endGroup().literal("|").startNamedGroup("gIngredientModifiers").anyOf("@\\-&?").zeroOrMore().endGroup().optional().startNamedGroup("gIngredientRecipeAnchor").literal("./").endGroup().optional().startGroup().startGroup().startNamedGroup("gmIngredientName").notAnyOf(nonWordChar).oneOrMore().startGroup().whitespace().oneOrMore().notAnyOf(nonWordChar).oneOrMore().endGroup().oneOrMore().endGroup().positiveLookahead("\\s*(?:\\{[^\\}]*\\}|\\([^)]*\\))").endGroup().or().startNamedGroup("gsIngredientName").notAnyOf(nonWordChar).zeroOrMore().notAnyOf("\\." + nonWordChar).endGroup().endGroup().startGroup().literal("{").startNamedGroup("gIngredientQuantityModifier").literal("=").exactly(1).endGroup().optional().startNamedGroup("gIngredientQuantity").startGroup().notAnyOf("}|%").oneOrMore().endGroup().optional().startGroup().literal("%").notAnyOf("|}").oneOrMore().lazy().endGroup().optional().startGroup().literal("|").notAnyOf("}").oneOrMore().lazy().endGroup().zeroOrMore().endGroup().literal("}").endGroup().optional().startGroup().literal("(").startNamedGroup("gIngredientPreparation").notAnyOf(")").oneOrMore().lazy().endGroup().literal(")").endGroup().optional().toRegExp();
|
|
280
|
+
var ingredientWithGroupKeyRegex = d().literal("@|").startNamedGroup("gIngredientGroupKey").notAnyOf(nonWordCharStrict + "/").oneOrMore().endGroup().startGroup().literal("/").startNamedGroup("gIngredientSubgroupKey").notAnyOf(nonWordCharStrict).oneOrMore().endGroup().endGroup().optional().literal("|").startNamedGroup("gIngredientModifiers").anyOf("@\\-&?").zeroOrMore().endGroup().optional().startNamedGroup("gIngredientRecipeAnchor").literal("./").endGroup().optional().startGroup().startGroup().startNamedGroup("gmIngredientName").notAnyOf(nonWordChar).oneOrMore().startGroup().whitespace().oneOrMore().notAnyOf(nonWordChar).oneOrMore().endGroup().oneOrMore().endGroup().positiveLookahead("\\s*(?:\\{[^\\}]*\\}|\\([^)]*\\))").endGroup().or().startNamedGroup("gsIngredientName").notAnyOf(nonWordChar).zeroOrMore().notAnyOf("\\." + nonWordChar).endGroup().endGroup().startGroup().literal("{").startNamedGroup("gIngredientQuantityModifier").literal("=").exactly(1).endGroup().optional().startNamedGroup("gIngredientQuantity").startGroup().notAnyOf("}|%").oneOrMore().endGroup().optional().startGroup().literal("%").notAnyOf("|}").oneOrMore().lazy().endGroup().optional().startGroup().literal("|").notAnyOf("}").oneOrMore().lazy().endGroup().zeroOrMore().endGroup().literal("}").endGroup().optional().startGroup().literal("(").startNamedGroup("gIngredientPreparation").notAnyOf(")").oneOrMore().lazy().endGroup().literal(")").endGroup().optional().toRegExp();
|
|
281
281
|
var ingredientAliasRegex = d().startAnchor().startNamedGroup("ingredientListName").notAnyOf("|").oneOrMore().endGroup().literal("|").startNamedGroup("ingredientDisplayName").notAnyOf("|").oneOrMore().endGroup().endAnchor().toRegExp();
|
|
282
282
|
var cookwareRegex = d().literal("#").startNamedGroup("cookwareModifiers").anyOf("\\-&?").zeroOrMore().endGroup().startGroup().startGroup().startNamedGroup("mCookwareName").notAnyOf(nonWordChar).oneOrMore().startGroup().whitespace().oneOrMore().notAnyOf(nonWordChar).oneOrMore().endGroup().oneOrMore().endGroup().positiveLookahead("\\s*(?:\\{[^\\}]*\\})").endGroup().or().startNamedGroup("sCookwareName").notAnyOf(nonWordChar).zeroOrMore().notAnyOf("\\." + nonWordChar).endGroup().endGroup().startGroup().literal("{").startNamedGroup("cookwareQuantity").anyCharacter().zeroOrMore().lazy().endGroup().literal("}").endGroup().optional().toRegExp();
|
|
283
283
|
var timerRegex = d().literal("~").startNamedGroup("timerName").anyCharacter().zeroOrMore().lazy().endGroup().literal("{").startNamedGroup("timerQuantity").anyCharacter().oneOrMore().lazy().endGroup().startGroup().literal("%").startNamedGroup("timerUnit").anyCharacter().oneOrMore().lazy().endGroup().endGroup().optional().literal("}").toRegExp();
|
|
@@ -2779,6 +2779,7 @@ var _Recipe = class _Recipe {
|
|
|
2779
2779
|
*/
|
|
2780
2780
|
__publicField(this, "servings");
|
|
2781
2781
|
_Recipe.itemCounts.set(this, 0);
|
|
2782
|
+
_Recipe.subgroupIndices.set(this, /* @__PURE__ */ new Map());
|
|
2782
2783
|
if (content) {
|
|
2783
2784
|
this.parse(content);
|
|
2784
2785
|
}
|
|
@@ -2996,6 +2997,7 @@ var _Recipe = class _Recipe {
|
|
|
2996
2997
|
if (!match?.groups) return;
|
|
2997
2998
|
const groups = match.groups;
|
|
2998
2999
|
const groupKey = groups.gIngredientGroupKey;
|
|
3000
|
+
const subgroupKey = groups.gIngredientSubgroupKey;
|
|
2999
3001
|
let name = groups.gmIngredientName || groups.gsIngredientName;
|
|
3000
3002
|
const preparation = groups.gIngredientPreparation;
|
|
3001
3003
|
const modifiers = groups.gIngredientModifiers;
|
|
@@ -3063,7 +3065,8 @@ var _Recipe = class _Recipe {
|
|
|
3063
3065
|
if (itemQuantity) {
|
|
3064
3066
|
Object.assign(alternative, itemQuantity);
|
|
3065
3067
|
}
|
|
3066
|
-
const
|
|
3068
|
+
const existingSubgroups = this.choices.ingredientGroups.get(groupKey);
|
|
3069
|
+
const existingAlternativesFlat = existingSubgroups?.flat();
|
|
3067
3070
|
function upsertAlternativeToIngredient(ingredients, ingredientIdx, newAlternativeIdx) {
|
|
3068
3071
|
const ingredient = ingredients[ingredientIdx];
|
|
3069
3072
|
if (ingredient) {
|
|
@@ -3074,8 +3077,8 @@ var _Recipe = class _Recipe {
|
|
|
3074
3077
|
}
|
|
3075
3078
|
}
|
|
3076
3079
|
}
|
|
3077
|
-
if (
|
|
3078
|
-
for (const alt of
|
|
3080
|
+
if (existingAlternativesFlat) {
|
|
3081
|
+
for (const alt of existingAlternativesFlat) {
|
|
3079
3082
|
upsertAlternativeToIngredient(this.ingredients, alt.index, idxInList);
|
|
3080
3083
|
upsertAlternativeToIngredient(this.ingredients, idxInList, alt.index);
|
|
3081
3084
|
}
|
|
@@ -3087,14 +3090,35 @@ var _Recipe = class _Recipe {
|
|
|
3087
3090
|
group: groupKey,
|
|
3088
3091
|
alternatives: [alternative]
|
|
3089
3092
|
};
|
|
3093
|
+
if (subgroupKey !== void 0) {
|
|
3094
|
+
newItem.subgroup = subgroupKey;
|
|
3095
|
+
}
|
|
3090
3096
|
items.push(newItem);
|
|
3091
3097
|
const choiceAlternative = deepClone(alternative);
|
|
3092
3098
|
choiceAlternative.itemId = id;
|
|
3093
3099
|
const existingChoice = this.choices.ingredientGroups.get(groupKey);
|
|
3100
|
+
const sgMap = _Recipe.subgroupIndices.get(this);
|
|
3094
3101
|
if (!existingChoice) {
|
|
3095
|
-
this.choices.ingredientGroups.set(groupKey, [choiceAlternative]);
|
|
3102
|
+
this.choices.ingredientGroups.set(groupKey, [[choiceAlternative]]);
|
|
3103
|
+
if (subgroupKey !== void 0) {
|
|
3104
|
+
sgMap.set(groupKey, /* @__PURE__ */ new Map([[subgroupKey, 0]]));
|
|
3105
|
+
}
|
|
3106
|
+
} else if (subgroupKey !== void 0) {
|
|
3107
|
+
const groupSgMap = sgMap.get(groupKey);
|
|
3108
|
+
const existingIdx = groupSgMap?.get(subgroupKey);
|
|
3109
|
+
if (existingIdx !== void 0) {
|
|
3110
|
+
existingChoice[existingIdx].push(choiceAlternative);
|
|
3111
|
+
} else {
|
|
3112
|
+
const newIdx = existingChoice.length;
|
|
3113
|
+
existingChoice.push([choiceAlternative]);
|
|
3114
|
+
if (!groupSgMap) {
|
|
3115
|
+
sgMap.set(groupKey, /* @__PURE__ */ new Map([[subgroupKey, newIdx]]));
|
|
3116
|
+
} else {
|
|
3117
|
+
groupSgMap.set(subgroupKey, newIdx);
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3096
3120
|
} else {
|
|
3097
|
-
existingChoice.push(choiceAlternative);
|
|
3121
|
+
existingChoice.push([choiceAlternative]);
|
|
3098
3122
|
}
|
|
3099
3123
|
}
|
|
3100
3124
|
/**
|
|
@@ -3151,15 +3175,16 @@ var _Recipe = class _Recipe {
|
|
|
3151
3175
|
(item2) => item2.type === "ingredient"
|
|
3152
3176
|
)) {
|
|
3153
3177
|
const isGrouped = "group" in item && item.group !== void 0;
|
|
3154
|
-
const
|
|
3178
|
+
const groupSubgroups = isGrouped ? this.choices.ingredientGroups.get(item.group) : void 0;
|
|
3155
3179
|
let selectedAltIndex = 0;
|
|
3156
3180
|
let isSelected;
|
|
3157
3181
|
let hasExplicitChoice;
|
|
3158
3182
|
if (isGrouped) {
|
|
3159
3183
|
const groupChoice = choices?.ingredientGroups?.get(item.group);
|
|
3160
3184
|
hasExplicitChoice = groupChoice !== void 0;
|
|
3161
|
-
const
|
|
3162
|
-
|
|
3185
|
+
const targetSubgroupIndex = groupChoice ?? 0;
|
|
3186
|
+
const selectedSubgroup = groupSubgroups?.[targetSubgroupIndex];
|
|
3187
|
+
isSelected = selectedSubgroup?.some((alt) => alt.itemId === item.id) ?? false;
|
|
3163
3188
|
} else {
|
|
3164
3189
|
const itemChoice = choices?.ingredientItems?.get(item.id);
|
|
3165
3190
|
hasExplicitChoice = itemChoice !== void 0;
|
|
@@ -3169,8 +3194,8 @@ var _Recipe = class _Recipe {
|
|
|
3169
3194
|
const alternative = item.alternatives[selectedAltIndex];
|
|
3170
3195
|
if (!alternative || !isSelected) continue;
|
|
3171
3196
|
selectedIndices.add(alternative.index);
|
|
3172
|
-
const
|
|
3173
|
-
for (const alt of
|
|
3197
|
+
const allAltsFlat = isGrouped ? groupSubgroups.flat() : item.alternatives;
|
|
3198
|
+
for (const alt of allAltsFlat) {
|
|
3174
3199
|
referencedIndices.add(alt.index);
|
|
3175
3200
|
}
|
|
3176
3201
|
if (!alternative.quantity) continue;
|
|
@@ -3182,10 +3207,34 @@ var _Recipe = class _Recipe {
|
|
|
3182
3207
|
};
|
|
3183
3208
|
const quantityEntry = alternative.equivalents?.length ? { or: [baseQty, ...alternative.equivalents] } : baseQty;
|
|
3184
3209
|
let alternativeRefs;
|
|
3185
|
-
if (!hasExplicitChoice &&
|
|
3186
|
-
|
|
3187
|
-
(
|
|
3188
|
-
)
|
|
3210
|
+
if (!hasExplicitChoice && groupSubgroups && groupSubgroups.length > 1) {
|
|
3211
|
+
const currentSubgroupIdx = groupSubgroups.findIndex(
|
|
3212
|
+
(sg) => sg.some((alt) => alt.itemId === item.id)
|
|
3213
|
+
);
|
|
3214
|
+
alternativeRefs = groupSubgroups.filter((_, idx) => idx !== currentSubgroupIdx).flatMap(
|
|
3215
|
+
(subgroup) => subgroup.map((otherAlt) => {
|
|
3216
|
+
const ref = {
|
|
3217
|
+
index: otherAlt.index
|
|
3218
|
+
};
|
|
3219
|
+
if (otherAlt.quantity) {
|
|
3220
|
+
const altQty = {
|
|
3221
|
+
quantity: otherAlt.quantity,
|
|
3222
|
+
...otherAlt.unit && {
|
|
3223
|
+
unit: otherAlt.unit.name
|
|
3224
|
+
},
|
|
3225
|
+
...otherAlt.equivalents && {
|
|
3226
|
+
equivalents: otherAlt.equivalents.map(
|
|
3227
|
+
(eq) => toPlainUnit(eq)
|
|
3228
|
+
)
|
|
3229
|
+
}
|
|
3230
|
+
};
|
|
3231
|
+
ref.quantities = [altQty];
|
|
3232
|
+
}
|
|
3233
|
+
return ref;
|
|
3234
|
+
})
|
|
3235
|
+
);
|
|
3236
|
+
} else if (!hasExplicitChoice && !isGrouped && allAltsFlat.length > 1) {
|
|
3237
|
+
alternativeRefs = allAltsFlat.filter((alt) => alt.index !== alternative.index).map((otherAlt) => {
|
|
3189
3238
|
const ref = { index: otherAlt.index };
|
|
3190
3239
|
if (otherAlt.quantity) {
|
|
3191
3240
|
const altQty = {
|
|
@@ -3603,8 +3652,10 @@ var _Recipe = class _Recipe {
|
|
|
3603
3652
|
}
|
|
3604
3653
|
}
|
|
3605
3654
|
}
|
|
3606
|
-
for (const
|
|
3607
|
-
|
|
3655
|
+
for (const subgroups of newRecipe.choices.ingredientGroups.values()) {
|
|
3656
|
+
for (const subgroup of subgroups) {
|
|
3657
|
+
scaleAlternativesBy(subgroup, factor);
|
|
3658
|
+
}
|
|
3608
3659
|
}
|
|
3609
3660
|
for (const alternatives of newRecipe.choices.ingredientItems.values()) {
|
|
3610
3661
|
scaleAlternativesBy(alternatives, factor);
|
|
@@ -3791,8 +3842,10 @@ var _Recipe = class _Recipe {
|
|
|
3791
3842
|
}
|
|
3792
3843
|
}
|
|
3793
3844
|
}
|
|
3794
|
-
for (const
|
|
3795
|
-
|
|
3845
|
+
for (const subgroups of newRecipe.choices.ingredientGroups.values()) {
|
|
3846
|
+
for (const subgroup of subgroups) {
|
|
3847
|
+
convertAlternatives(subgroup);
|
|
3848
|
+
}
|
|
3796
3849
|
}
|
|
3797
3850
|
for (const alternatives of newRecipe.choices.ingredientItems.values()) {
|
|
3798
3851
|
convertAlternatives(alternatives);
|
|
@@ -3844,6 +3897,11 @@ __publicField(_Recipe, "unitSystems", /* @__PURE__ */ new WeakMap());
|
|
|
3844
3897
|
* Used for giving ID numbers to items during parsing.
|
|
3845
3898
|
*/
|
|
3846
3899
|
__publicField(_Recipe, "itemCounts", /* @__PURE__ */ new WeakMap());
|
|
3900
|
+
/**
|
|
3901
|
+
* External storage for subgroup index tracking during parsing.
|
|
3902
|
+
* Maps groupKey → subgroupKey → index within the subgroups array.
|
|
3903
|
+
*/
|
|
3904
|
+
__publicField(_Recipe, "subgroupIndices", /* @__PURE__ */ new WeakMap());
|
|
3847
3905
|
var Recipe = _Recipe;
|
|
3848
3906
|
|
|
3849
3907
|
// src/classes/shopping_list.ts
|
|
@@ -4681,10 +4739,10 @@ function isGroupedItem(item) {
|
|
|
4681
4739
|
function isAlternativeSelected(recipe, choices, item, alternativeIndex) {
|
|
4682
4740
|
if (item.group) {
|
|
4683
4741
|
const selectedIndex2 = choices?.ingredientGroups?.get(item.group);
|
|
4684
|
-
const
|
|
4685
|
-
if (
|
|
4686
|
-
const
|
|
4687
|
-
return
|
|
4742
|
+
const groupSubgroups = recipe.choices.ingredientGroups.get(item.group);
|
|
4743
|
+
if (groupSubgroups && selectedIndex2 !== void 0 && selectedIndex2 < groupSubgroups.length) {
|
|
4744
|
+
const selectedSubgroup = groupSubgroups[selectedIndex2];
|
|
4745
|
+
return selectedSubgroup?.some((alt) => alt.itemId === item.id);
|
|
4688
4746
|
}
|
|
4689
4747
|
return false;
|
|
4690
4748
|
}
|