@uniformdev/context 20.6.2-alpha.10 → 20.6.5-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/api.d.mts +8 -1
- package/dist/api/api.d.ts +8 -1
- package/dist/api/api.js +8 -2
- package/dist/api/api.mjs +8 -2
- package/dist/index.d.mts +4 -33
- package/dist/index.d.ts +4 -33
- package/dist/index.esm.js +41 -213
- package/dist/index.js +42 -218
- package/dist/index.mjs +41 -213
- package/dist/{types-CzIkFCDD.d.mts → types-EJl31yuP.d.mts} +24 -96
- package/dist/{types-CzIkFCDD.d.ts → types-EJl31yuP.d.ts} +24 -96
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
@@ -516,7 +516,7 @@ var GroupCriteriaEvaluator = class {
|
|
516
516
|
_evaluators = new WeakMap();
|
517
517
|
|
518
518
|
// src/placement/criteria/evaluateVariantMatch.ts
|
519
|
-
function evaluateVariantMatch(variantId, match, vec, onLogMessage
|
519
|
+
function evaluateVariantMatch(variantId, match, vec, onLogMessage) {
|
520
520
|
onLogMessage == null ? void 0 : onLogMessage(["info", 301, "GROUP", { id: variantId, op: match == null ? void 0 : match.op }]);
|
521
521
|
let result;
|
522
522
|
try {
|
@@ -524,9 +524,9 @@ function evaluateVariantMatch(variantId, match, vec, onLogMessage, quirks) {
|
|
524
524
|
onLogMessage == null ? void 0 : onLogMessage(["info", 302, { matched: true, description: "default variation" }]);
|
525
525
|
result = true;
|
526
526
|
} else if (!match.op || match.op === "&") {
|
527
|
-
result = match.crit.every((c) =>
|
527
|
+
result = match.crit.every((c) => evaluateDimensionMatch(c, vec, onLogMessage));
|
528
528
|
} else {
|
529
|
-
result = match.crit.some((c) =>
|
529
|
+
result = match.crit.some((c) => evaluateDimensionMatch(c, vec, onLogMessage));
|
530
530
|
}
|
531
531
|
onLogMessage == null ? void 0 : onLogMessage(["info", 303, result]);
|
532
532
|
} finally {
|
@@ -534,16 +534,9 @@ function evaluateVariantMatch(variantId, match, vec, onLogMessage, quirks) {
|
|
534
534
|
}
|
535
535
|
return result;
|
536
536
|
}
|
537
|
-
function evaluateMatch(crit, vec, quirks, onLogMessage) {
|
538
|
-
if ("t" in crit && crit.t === "q") {
|
539
|
-
return evaluateQuirkMatch(crit, quirks, onLogMessage);
|
540
|
-
} else {
|
541
|
-
return evaluateDimensionMatch(crit, vec, onLogMessage);
|
542
|
-
}
|
543
|
-
}
|
544
537
|
function evaluateDimensionMatch(crit, vec, onLogMessage) {
|
545
538
|
var _a, _b;
|
546
|
-
const { l: lhs
|
539
|
+
const { op, l: lhs } = crit;
|
547
540
|
const lhsScore = (_a = vec[lhs]) != null ? _a : 0;
|
548
541
|
if (op === "^") {
|
549
542
|
const [cat] = lhs.split(ENR_SEPARATOR);
|
@@ -610,65 +603,33 @@ function evaluateDimensionMatch(crit, vec, onLogMessage) {
|
|
610
603
|
}
|
611
604
|
if (op === ">") {
|
612
605
|
const result = lhsScore > rhsScore;
|
613
|
-
|
606
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
614
607
|
return result;
|
615
608
|
} else if (op === ">=") {
|
616
609
|
const result = lhsScore >= rhsScore;
|
617
|
-
|
610
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
618
611
|
return result;
|
619
612
|
} else if (op === "<") {
|
620
613
|
const result = lhsScore < rhsScore;
|
621
|
-
|
614
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
622
615
|
return result;
|
623
616
|
} else if (op === "<=") {
|
624
617
|
const result = lhsScore <= rhsScore;
|
625
|
-
|
618
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
626
619
|
return result;
|
627
620
|
} else if (op === "=") {
|
628
621
|
const result = lhsScore === rhsScore;
|
629
|
-
|
622
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
630
623
|
return result;
|
631
624
|
} else if (op === "!=") {
|
632
625
|
const result = lhsScore !== rhsScore;
|
633
|
-
|
626
|
+
explain(onLogMessage, result, crit, lhsScore, rhsScore);
|
634
627
|
return result;
|
635
628
|
} else {
|
636
|
-
|
637
|
-
"error",
|
638
|
-
302,
|
639
|
-
{
|
640
|
-
matched: false,
|
641
|
-
description: `${crit.l} ${crit.op} ${crit.rDim ? `${crit.rDim}` : crit.r}: Unknown op ${crit.op}.`
|
642
|
-
}
|
643
|
-
]);
|
644
|
-
return false;
|
645
|
-
}
|
646
|
-
}
|
647
|
-
function evaluateQuirkMatch(crit, quirks, onLogMessage) {
|
648
|
-
var _a;
|
649
|
-
const { l: targetQuirk, op, r: targetValue } = crit;
|
650
|
-
const targetQuirkValue = (_a = quirks[targetQuirk]) != null ? _a : "";
|
651
|
-
if (op === "=") {
|
652
|
-
const result = targetQuirkValue === targetValue;
|
653
|
-
explainQuirk(onLogMessage, result, crit, targetQuirkValue);
|
654
|
-
return result;
|
655
|
-
} else if (op === "!=") {
|
656
|
-
const result = targetQuirkValue !== targetValue;
|
657
|
-
explainQuirk(onLogMessage, result, crit, targetQuirkValue);
|
658
|
-
return result;
|
659
|
-
} else {
|
660
|
-
onLogMessage == null ? void 0 : onLogMessage([
|
661
|
-
"error",
|
662
|
-
302,
|
663
|
-
{
|
664
|
-
matched: false,
|
665
|
-
description: `Quirk ${crit.l} ${crit.op} ${crit.r}: Unknown quirk op ${crit.op}.`
|
666
|
-
}
|
667
|
-
]);
|
668
|
-
return false;
|
629
|
+
throw new Error(`Unknown op: ${op}`);
|
669
630
|
}
|
670
631
|
}
|
671
|
-
function
|
632
|
+
function explain(onLogMessage, result, crit, lhsScore, rhsScore) {
|
672
633
|
onLogMessage == null ? void 0 : onLogMessage([
|
673
634
|
"info",
|
674
635
|
302,
|
@@ -678,20 +639,9 @@ function explainScore(onLogMessage, result, crit, lhsScore, rhsScore) {
|
|
678
639
|
}
|
679
640
|
]);
|
680
641
|
}
|
681
|
-
function explainQuirk(onLogMessage, result, crit, lhs) {
|
682
|
-
onLogMessage == null ? void 0 : onLogMessage([
|
683
|
-
"info",
|
684
|
-
302,
|
685
|
-
{
|
686
|
-
matched: result,
|
687
|
-
description: `Quirk ${crit.l}[${lhs}] ${crit.op} ${crit.r}`
|
688
|
-
}
|
689
|
-
]);
|
690
|
-
}
|
691
642
|
|
692
|
-
// src/placement/
|
693
|
-
|
694
|
-
function topDownCriteriaPersonalizationSelectionAlgorithm({
|
643
|
+
// src/placement/personalize.ts
|
644
|
+
function personalizeVariations({
|
695
645
|
name,
|
696
646
|
context,
|
697
647
|
variations,
|
@@ -701,34 +651,27 @@ function topDownCriteriaPersonalizationSelectionAlgorithm({
|
|
701
651
|
var _a, _b, _c;
|
702
652
|
onLogMessage == null ? void 0 : onLogMessage(["info", 300, "GROUP", { name, take }]);
|
703
653
|
try {
|
704
|
-
const
|
705
|
-
const
|
706
|
-
const
|
707
|
-
const
|
708
|
-
for (const
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
validVariation = { id: variation.id };
|
713
|
-
} else {
|
714
|
-
validVariation = variation;
|
715
|
-
}
|
716
|
-
if ((_a = validVariation.pz) == null ? void 0 : _a.crit.length) {
|
717
|
-
if (personalizationAllowed && variationMatches.length !== take && evaluateVariantMatch(variation.id, validVariation.pz, context.scores, onLogMessage, context.quirks)) {
|
718
|
-
variationMatches.push(validVariation);
|
654
|
+
const variantMatches = [];
|
655
|
+
const defaultVariants = [];
|
656
|
+
const needsConsent = context.requireConsentForPersonalization;
|
657
|
+
const canEvaluate = !needsConsent || context.storage.data.consent;
|
658
|
+
for (const variant of variations) {
|
659
|
+
if ((_a = variant.pz) == null ? void 0 : _a.crit.length) {
|
660
|
+
if (canEvaluate && variantMatches.length !== take && evaluateVariantMatch(variant.id, variant.pz, context.scores, onLogMessage)) {
|
661
|
+
variantMatches.push(variant);
|
719
662
|
}
|
720
663
|
} else {
|
721
|
-
|
664
|
+
defaultVariants.push(variant);
|
722
665
|
}
|
723
666
|
}
|
724
667
|
const result = [];
|
725
|
-
for (let i = 0; i <
|
668
|
+
for (let i = 0; i < variantMatches.length; i++) {
|
726
669
|
let isControl = (_b = context.storage.data.controlGroup) != null ? _b : false;
|
727
|
-
const
|
728
|
-
if (!isControl && typeof ((_c =
|
670
|
+
const variant = variantMatches[i];
|
671
|
+
if (!isControl && typeof ((_c = variant.pz) == null ? void 0 : _c.control) === "number") {
|
729
672
|
isControl = context.getPersonalizeVariantControl(name, i);
|
730
673
|
if (typeof isControl === "undefined") {
|
731
|
-
isControl = rollForControlGroup(
|
674
|
+
isControl = rollForControlGroup(variant.pz.control);
|
732
675
|
context.storage.updateData([
|
733
676
|
{
|
734
677
|
type: "setpersonalizecontrol",
|
@@ -741,13 +684,13 @@ function topDownCriteriaPersonalizationSelectionAlgorithm({
|
|
741
684
|
]);
|
742
685
|
}
|
743
686
|
}
|
744
|
-
let variantToAdd =
|
687
|
+
let variantToAdd = variant;
|
745
688
|
if (isControl) {
|
746
|
-
const defaultReplacement =
|
689
|
+
const defaultReplacement = defaultVariants.shift();
|
747
690
|
if (defaultReplacement) {
|
748
691
|
variantToAdd = {
|
749
692
|
...defaultReplacement,
|
750
|
-
id:
|
693
|
+
id: variant.id
|
751
694
|
};
|
752
695
|
} else {
|
753
696
|
variantToAdd = void 0;
|
@@ -757,8 +700,8 @@ function topDownCriteriaPersonalizationSelectionAlgorithm({
|
|
757
700
|
result.push({ ...variantToAdd, control: isControl });
|
758
701
|
}
|
759
702
|
}
|
760
|
-
while (result.length < take &&
|
761
|
-
result.push({ ...
|
703
|
+
while (result.length < take && defaultVariants.length) {
|
704
|
+
result.push({ ...defaultVariants.shift(), control: false });
|
762
705
|
}
|
763
706
|
const personalized = result.some((v) => {
|
764
707
|
var _a2;
|
@@ -773,82 +716,7 @@ function topDownCriteriaPersonalizationSelectionAlgorithm({
|
|
773
716
|
}
|
774
717
|
}
|
775
718
|
|
776
|
-
// src/placement/
|
777
|
-
function personalizeVariations(options) {
|
778
|
-
return topDownCriteriaPersonalizationSelectionAlgorithm(options);
|
779
|
-
}
|
780
|
-
|
781
|
-
// src/placement/strongestScorePersonalizationSelectionAlgorithm.ts
|
782
|
-
var STRONGEST_SCORE_PERSONALIZATION_ALGORITHM = "ssc";
|
783
|
-
function strongestScorePersonalizationSelectionAlgorithm({
|
784
|
-
name,
|
785
|
-
context,
|
786
|
-
variations,
|
787
|
-
take = 1,
|
788
|
-
onLogMessage
|
789
|
-
}) {
|
790
|
-
var _a, _b;
|
791
|
-
onLogMessage == null ? void 0 : onLogMessage(["info", 300, "GROUP", { name, take }]);
|
792
|
-
try {
|
793
|
-
const variationMatches = [];
|
794
|
-
const defaultVariations = [];
|
795
|
-
const needsConsentToPersonalize = context.requireConsentForPersonalization;
|
796
|
-
const isInGlobalControlGroup = (_a = context.storage.data.controlGroup) != null ? _a : false;
|
797
|
-
const personalizationAllowed = !needsConsentToPersonalize || context.storage.data.consent;
|
798
|
-
for (const variation of variations) {
|
799
|
-
const isInvalidFormat = variation.pz && (typeof variation.pz !== "object" || variation.pz === null);
|
800
|
-
let validVariation;
|
801
|
-
if (isInvalidFormat) {
|
802
|
-
validVariation = { id: variation.id };
|
803
|
-
} else {
|
804
|
-
validVariation = variation;
|
805
|
-
}
|
806
|
-
if ((_b = validVariation.pz) == null ? void 0 : _b.dim) {
|
807
|
-
if (!personalizationAllowed) {
|
808
|
-
continue;
|
809
|
-
}
|
810
|
-
const score = context.scores[validVariation.pz.dim];
|
811
|
-
if (score === void 0 || score <= 0) {
|
812
|
-
continue;
|
813
|
-
}
|
814
|
-
variationMatches.push({ variation: validVariation, score });
|
815
|
-
} else {
|
816
|
-
defaultVariations.push(validVariation);
|
817
|
-
}
|
818
|
-
}
|
819
|
-
variationMatches.sort((a, b) => b.score - a.score);
|
820
|
-
const result = [];
|
821
|
-
for (let i = 0; i < variationMatches.length; i++) {
|
822
|
-
const variationMatch = variationMatches[i];
|
823
|
-
let variantToAdd = variationMatch.variation;
|
824
|
-
if (isInGlobalControlGroup) {
|
825
|
-
const defaultReplacement = defaultVariations.shift();
|
826
|
-
if (defaultReplacement) {
|
827
|
-
variantToAdd = {
|
828
|
-
...defaultReplacement,
|
829
|
-
id: variationMatch.variation.id
|
830
|
-
};
|
831
|
-
} else {
|
832
|
-
variantToAdd = void 0;
|
833
|
-
}
|
834
|
-
}
|
835
|
-
if (variantToAdd) {
|
836
|
-
result.push({ ...variantToAdd, control: isInGlobalControlGroup });
|
837
|
-
}
|
838
|
-
}
|
839
|
-
while (result.length < take && defaultVariations.length) {
|
840
|
-
result.push({ ...defaultVariations.shift(), control: false });
|
841
|
-
}
|
842
|
-
return {
|
843
|
-
personalized: variationMatches.length > 0 && !isInGlobalControlGroup,
|
844
|
-
variations: result
|
845
|
-
};
|
846
|
-
} finally {
|
847
|
-
onLogMessage == null ? void 0 : onLogMessage(["info", 300, "ENDGROUP"]);
|
848
|
-
}
|
849
|
-
}
|
850
|
-
|
851
|
-
// src/placement/normalizeVariationDistributions.ts
|
719
|
+
// src/placement/test.ts
|
852
720
|
var normalizeVariationDistributions = (variations) => {
|
853
721
|
const { values, total, missingDistribution } = variations.reduce(
|
854
722
|
(previous, current) => {
|
@@ -867,12 +735,7 @@ var normalizeVariationDistributions = (variations) => {
|
|
867
735
|
}
|
868
736
|
);
|
869
737
|
if (total > 100) {
|
870
|
-
|
871
|
-
values.forEach((value, index) => {
|
872
|
-
if (typeof value === "number") {
|
873
|
-
values[index] = value * autoScaleFactor;
|
874
|
-
}
|
875
|
-
});
|
738
|
+
throw new Error(`Total distribution ${total} is over the maximum 100.`);
|
876
739
|
} else if (total < 100) {
|
877
740
|
const remainder = 100 - total;
|
878
741
|
const missingSlice = remainder / missingDistribution;
|
@@ -884,8 +747,6 @@ var normalizeVariationDistributions = (variations) => {
|
|
884
747
|
}
|
885
748
|
return values;
|
886
749
|
};
|
887
|
-
|
888
|
-
// src/placement/testVariations.ts
|
889
750
|
var testVariations = ({
|
890
751
|
name,
|
891
752
|
context,
|
@@ -912,11 +773,11 @@ var testVariations = ({
|
|
912
773
|
}
|
913
774
|
if (!selectedVariant) {
|
914
775
|
const distributions = normalizeVariationDistributions(variations);
|
915
|
-
const random = Math.
|
776
|
+
const random = Math.random() * 100;
|
916
777
|
let distributionOffset = 0;
|
917
778
|
selectedVariant = variations.find((variant, index) => {
|
918
779
|
const distribution = distributions[index];
|
919
|
-
if (
|
780
|
+
if (random >= distributionOffset && random < distributionOffset + distribution) {
|
920
781
|
return variant;
|
921
782
|
}
|
922
783
|
distributionOffset += distribution;
|
@@ -1652,12 +1513,11 @@ import { dequal as dequal5 } from "dequal/lite";
|
|
1652
1513
|
import mitt3 from "mitt";
|
1653
1514
|
var CONTEXTUAL_EDITING_TEST_NAME = "contextual_editing_test";
|
1654
1515
|
var CONTEXTUAL_EDITING_TEST_SELECTED_VARIANT_ID = "contextual_editing_test_selected_variant";
|
1655
|
-
var
|
1516
|
+
var _serverTransitionState, _scores, _state, _pzCache, _plugins, _commands, _requireConsentForPersonalization, _mitt3, _Context_instances, emitTest_fn, updateGoals_fn, updateComputedScores_fn, calculateScores_fn;
|
1656
1517
|
var Context = class {
|
1657
1518
|
constructor(options) {
|
1658
1519
|
__privateAdd(this, _Context_instances);
|
1659
1520
|
__publicField(this, "manifest");
|
1660
|
-
__privateAdd(this, _personalizationSelectionAlgorithms);
|
1661
1521
|
__privateAdd(this, _serverTransitionState);
|
1662
1522
|
__privateAdd(this, _scores, {});
|
1663
1523
|
__privateAdd(this, _state);
|
@@ -1674,7 +1534,7 @@ var Context = class {
|
|
1674
1534
|
off: __privateGet(this, _mitt3).off
|
1675
1535
|
});
|
1676
1536
|
__publicField(this, "storage");
|
1677
|
-
var _a, _b
|
1537
|
+
var _a, _b;
|
1678
1538
|
const { manifest, ...storageOptions } = options;
|
1679
1539
|
__privateSet(this, _state, {});
|
1680
1540
|
__privateSet(this, _plugins, options.plugins);
|
@@ -1682,20 +1542,7 @@ var Context = class {
|
|
1682
1542
|
if (typeof options.transitionStore !== "undefined") {
|
1683
1543
|
__privateSet(this, _commands, []);
|
1684
1544
|
}
|
1685
|
-
__privateSet(this, _personalizationSelectionAlgorithms, {
|
1686
|
-
[TOP_DOWN_CRITERIA_PERSONALIZATION_ALGORITHM]: topDownCriteriaPersonalizationSelectionAlgorithm,
|
1687
|
-
[STRONGEST_SCORE_PERSONALIZATION_ALGORITHM]: strongestScorePersonalizationSelectionAlgorithm
|
1688
|
-
});
|
1689
1545
|
(_a = __privateGet(this, _plugins)) == null ? void 0 : _a.forEach((plugin) => {
|
1690
|
-
if (!plugin.personalizationSelectionAlgorithms) {
|
1691
|
-
return;
|
1692
|
-
}
|
1693
|
-
__privateSet(this, _personalizationSelectionAlgorithms, {
|
1694
|
-
...__privateGet(this, _personalizationSelectionAlgorithms),
|
1695
|
-
...plugin.personalizationSelectionAlgorithms
|
1696
|
-
});
|
1697
|
-
});
|
1698
|
-
(_b = __privateGet(this, _plugins)) == null ? void 0 : _b.forEach((plugin) => {
|
1699
1546
|
if (!plugin.logDrain) {
|
1700
1547
|
return;
|
1701
1548
|
}
|
@@ -1746,7 +1593,7 @@ var Context = class {
|
|
1746
1593
|
__privateGet(this, _mitt3).emit("quirksUpdated", quirks.quirks);
|
1747
1594
|
__privateGet(this, _mitt3).emit("log", ["info", 4, quirks.quirks]);
|
1748
1595
|
});
|
1749
|
-
(
|
1596
|
+
(_b = __privateGet(this, _plugins)) == null ? void 0 : _b.forEach((plugin) => {
|
1750
1597
|
if (!plugin.init) {
|
1751
1598
|
return;
|
1752
1599
|
}
|
@@ -1996,17 +1843,7 @@ var Context = class {
|
|
1996
1843
|
}
|
1997
1844
|
/** Executes a personalized placement with a given set of variants */
|
1998
1845
|
personalize(options) {
|
1999
|
-
|
2000
|
-
const algorithmName = (_a = options.algorithm) != null ? _a : TOP_DOWN_CRITERIA_PERSONALIZATION_ALGORITHM;
|
2001
|
-
const algorithm = __privateGet(this, _personalizationSelectionAlgorithms)[algorithmName];
|
2002
|
-
if (!algorithm) {
|
2003
|
-
__privateGet(this, _mitt3).emit("log", ["warn", 304, { algorithm: algorithmName }]);
|
2004
|
-
return {
|
2005
|
-
personalized: false,
|
2006
|
-
variations: []
|
2007
|
-
};
|
2008
|
-
}
|
2009
|
-
const value = algorithm({
|
1846
|
+
const value = personalizeVariations({
|
2010
1847
|
...options,
|
2011
1848
|
context: this,
|
2012
1849
|
onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
|
@@ -2080,7 +1917,6 @@ var Context = class {
|
|
2080
1917
|
__privateGet(this, _mitt3).emit("personalizationResult", event);
|
2081
1918
|
}
|
2082
1919
|
};
|
2083
|
-
_personalizationSelectionAlgorithms = new WeakMap();
|
2084
1920
|
_serverTransitionState = new WeakMap();
|
2085
1921
|
_scores = new WeakMap();
|
2086
1922
|
_state = new WeakMap();
|
@@ -2676,10 +2512,6 @@ var messageContent = {
|
|
2676
2512
|
301: ({ id, op }) => ["personalization", `testing variation ${id} (${op === "|" ? "OR" : "AND"})`],
|
2677
2513
|
302: ({ matched, description }) => ["personalization", `${description} is ${matched}`],
|
2678
2514
|
303: (selected) => ["personalization", selected ? "selected variation" : "did not select variation"],
|
2679
|
-
304: ({ algorithm }) => [
|
2680
|
-
"personalization",
|
2681
|
-
`personalization selection algorithm '${algorithm}' not found. Hiding placement.`
|
2682
|
-
],
|
2683
2515
|
// TESTING
|
2684
2516
|
400: (name) => ["testing", `executing A/B test '${name}'`],
|
2685
2517
|
401: (testName) => ["testing", `${testName} is not registered in the manifest; it will not be run.`],
|
@@ -2784,9 +2616,7 @@ export {
|
|
2784
2616
|
PAIR_SEP,
|
2785
2617
|
QUIRK_SEP,
|
2786
2618
|
SERVER_STATE_ID,
|
2787
|
-
STRONGEST_SCORE_PERSONALIZATION_ALGORITHM,
|
2788
2619
|
ScriptType,
|
2789
|
-
TOP_DOWN_CRITERIA_PERSONALIZATION_ALGORITHM,
|
2790
2620
|
TYPE_SEP,
|
2791
2621
|
TransitionDataStore,
|
2792
2622
|
UNIFORM_DEFAULT_COOKIE_NAME,
|
@@ -2828,7 +2658,5 @@ export {
|
|
2828
2658
|
serializePersonalizeVariants,
|
2829
2659
|
serializeQuickConnect,
|
2830
2660
|
serializeQuirks,
|
2831
|
-
|
2832
|
-
testVariations,
|
2833
|
-
topDownCriteriaPersonalizationSelectionAlgorithm
|
2661
|
+
testVariations
|
2834
2662
|
};
|