@featurevisor/sdk 1.35.2 → 2.0.0

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 (86) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +2 -381
  3. package/coverage/clover.xml +707 -643
  4. package/coverage/coverage-final.json +11 -9
  5. package/coverage/lcov-report/{segments.ts.html → bucketer.ts.html} +155 -77
  6. package/coverage/lcov-report/child.ts.html +940 -0
  7. package/coverage/lcov-report/conditions.ts.html +107 -158
  8. package/coverage/lcov-report/datafileReader.ts.html +763 -103
  9. package/coverage/lcov-report/emitter.ts.html +77 -59
  10. package/coverage/lcov-report/evaluate.ts.html +689 -416
  11. package/coverage/lcov-report/events.ts.html +334 -0
  12. package/coverage/lcov-report/helpers.ts.html +184 -0
  13. package/coverage/lcov-report/{feature.ts.html → hooks.ts.html} +90 -237
  14. package/coverage/lcov-report/index.html +119 -89
  15. package/coverage/lcov-report/instance.ts.html +341 -773
  16. package/coverage/lcov-report/logger.ts.html +64 -64
  17. package/coverage/lcov.info +1433 -1223
  18. package/dist/bucketer.d.ts +11 -0
  19. package/dist/child.d.ts +26 -0
  20. package/dist/compareVersions.d.ts +4 -0
  21. package/dist/conditions.d.ts +4 -4
  22. package/dist/datafileReader.d.ts +26 -6
  23. package/dist/emitter.d.ts +8 -9
  24. package/dist/evaluate.d.ts +31 -29
  25. package/dist/events.d.ts +5 -0
  26. package/dist/helpers.d.ts +5 -0
  27. package/dist/hooks.d.ts +45 -0
  28. package/dist/index.d.ts +3 -2
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +1 -1
  32. package/dist/index.mjs.gz +0 -0
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/instance.d.ts +40 -72
  35. package/dist/logger.d.ts +6 -5
  36. package/dist/murmurhash.d.ts +1 -0
  37. package/jest.config.js +2 -0
  38. package/lib/bucketer.d.ts +11 -0
  39. package/lib/child.d.ts +26 -0
  40. package/lib/compareVersions.d.ts +4 -0
  41. package/lib/conditions.d.ts +4 -4
  42. package/lib/datafileReader.d.ts +26 -6
  43. package/lib/emitter.d.ts +8 -9
  44. package/lib/evaluate.d.ts +31 -29
  45. package/lib/events.d.ts +5 -0
  46. package/lib/helpers.d.ts +5 -0
  47. package/lib/hooks.d.ts +45 -0
  48. package/lib/index.d.ts +3 -2
  49. package/lib/instance.d.ts +40 -72
  50. package/lib/logger.d.ts +6 -5
  51. package/lib/murmurhash.d.ts +1 -0
  52. package/package.json +3 -5
  53. package/src/bucketer.spec.ts +165 -0
  54. package/src/bucketer.ts +84 -0
  55. package/src/child.spec.ts +267 -0
  56. package/src/child.ts +285 -0
  57. package/src/compareVersions.ts +93 -0
  58. package/src/conditions.spec.ts +563 -353
  59. package/src/conditions.ts +46 -63
  60. package/src/datafileReader.spec.ts +396 -84
  61. package/src/datafileReader.ts +280 -60
  62. package/src/emitter.spec.ts +27 -86
  63. package/src/emitter.ts +38 -32
  64. package/src/evaluate.ts +349 -258
  65. package/src/events.spec.ts +154 -0
  66. package/src/events.ts +83 -0
  67. package/src/helpers.ts +33 -0
  68. package/src/hooks.ts +88 -0
  69. package/src/index.ts +3 -2
  70. package/src/instance.spec.ts +305 -489
  71. package/src/instance.ts +247 -391
  72. package/src/logger.spec.ts +212 -134
  73. package/src/logger.ts +36 -36
  74. package/src/murmurhash.ts +71 -0
  75. package/coverage/lcov-report/bucket.ts.html +0 -502
  76. package/dist/bucket.d.ts +0 -30
  77. package/dist/feature.d.ts +0 -16
  78. package/dist/segments.d.ts +0 -5
  79. package/lib/bucket.d.ts +0 -30
  80. package/lib/feature.d.ts +0 -16
  81. package/lib/segments.d.ts +0 -5
  82. package/src/bucket.spec.ts +0 -37
  83. package/src/bucket.ts +0 -139
  84. package/src/feature.ts +0 -137
  85. package/src/segments.spec.ts +0 -468
  86. package/src/segments.ts +0 -58
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">95.3% </span>
26
+ <span class="strong">91.13% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>203/213</span>
28
+ <span class='fraction'>216/237</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">91.6% </span>
33
+ <span class="strong">88.23% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>131/143</span>
35
+ <span class='fraction'>135/153</span>
36
36
  </div>
37
37
 
38
38
 
@@ -44,9 +44,9 @@
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">95.19% </span>
47
+ <span class="strong">90.98% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>198/208</span>
49
+ <span class='fraction'>212/233</span>
50
50
  </div>
51
51
 
52
52
 
@@ -844,7 +844,98 @@
844
844
  <a name='L779'></a><a href='#L779'>779</a>
845
845
  <a name='L780'></a><a href='#L780'>780</a>
846
846
  <a name='L781'></a><a href='#L781'>781</a>
847
- <a name='L782'></a><a href='#L782'>782</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
847
+ <a name='L782'></a><a href='#L782'>782</a>
848
+ <a name='L783'></a><a href='#L783'>783</a>
849
+ <a name='L784'></a><a href='#L784'>784</a>
850
+ <a name='L785'></a><a href='#L785'>785</a>
851
+ <a name='L786'></a><a href='#L786'>786</a>
852
+ <a name='L787'></a><a href='#L787'>787</a>
853
+ <a name='L788'></a><a href='#L788'>788</a>
854
+ <a name='L789'></a><a href='#L789'>789</a>
855
+ <a name='L790'></a><a href='#L790'>790</a>
856
+ <a name='L791'></a><a href='#L791'>791</a>
857
+ <a name='L792'></a><a href='#L792'>792</a>
858
+ <a name='L793'></a><a href='#L793'>793</a>
859
+ <a name='L794'></a><a href='#L794'>794</a>
860
+ <a name='L795'></a><a href='#L795'>795</a>
861
+ <a name='L796'></a><a href='#L796'>796</a>
862
+ <a name='L797'></a><a href='#L797'>797</a>
863
+ <a name='L798'></a><a href='#L798'>798</a>
864
+ <a name='L799'></a><a href='#L799'>799</a>
865
+ <a name='L800'></a><a href='#L800'>800</a>
866
+ <a name='L801'></a><a href='#L801'>801</a>
867
+ <a name='L802'></a><a href='#L802'>802</a>
868
+ <a name='L803'></a><a href='#L803'>803</a>
869
+ <a name='L804'></a><a href='#L804'>804</a>
870
+ <a name='L805'></a><a href='#L805'>805</a>
871
+ <a name='L806'></a><a href='#L806'>806</a>
872
+ <a name='L807'></a><a href='#L807'>807</a>
873
+ <a name='L808'></a><a href='#L808'>808</a>
874
+ <a name='L809'></a><a href='#L809'>809</a>
875
+ <a name='L810'></a><a href='#L810'>810</a>
876
+ <a name='L811'></a><a href='#L811'>811</a>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a>
895
+ <a name='L830'></a><a href='#L830'>830</a>
896
+ <a name='L831'></a><a href='#L831'>831</a>
897
+ <a name='L832'></a><a href='#L832'>832</a>
898
+ <a name='L833'></a><a href='#L833'>833</a>
899
+ <a name='L834'></a><a href='#L834'>834</a>
900
+ <a name='L835'></a><a href='#L835'>835</a>
901
+ <a name='L836'></a><a href='#L836'>836</a>
902
+ <a name='L837'></a><a href='#L837'>837</a>
903
+ <a name='L838'></a><a href='#L838'>838</a>
904
+ <a name='L839'></a><a href='#L839'>839</a>
905
+ <a name='L840'></a><a href='#L840'>840</a>
906
+ <a name='L841'></a><a href='#L841'>841</a>
907
+ <a name='L842'></a><a href='#L842'>842</a>
908
+ <a name='L843'></a><a href='#L843'>843</a>
909
+ <a name='L844'></a><a href='#L844'>844</a>
910
+ <a name='L845'></a><a href='#L845'>845</a>
911
+ <a name='L846'></a><a href='#L846'>846</a>
912
+ <a name='L847'></a><a href='#L847'>847</a>
913
+ <a name='L848'></a><a href='#L848'>848</a>
914
+ <a name='L849'></a><a href='#L849'>849</a>
915
+ <a name='L850'></a><a href='#L850'>850</a>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a>
930
+ <a name='L865'></a><a href='#L865'>865</a>
931
+ <a name='L866'></a><a href='#L866'>866</a>
932
+ <a name='L867'></a><a href='#L867'>867</a>
933
+ <a name='L868'></a><a href='#L868'>868</a>
934
+ <a name='L869'></a><a href='#L869'>869</a>
935
+ <a name='L870'></a><a href='#L870'>870</a>
936
+ <a name='L871'></a><a href='#L871'>871</a>
937
+ <a name='L872'></a><a href='#L872'>872</a>
938
+ <a name='L873'></a><a href='#L873'>873</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
848
939
  <span class="cline-any cline-neutral">&nbsp;</span>
849
940
  <span class="cline-any cline-neutral">&nbsp;</span>
850
941
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -866,33 +957,34 @@
866
957
  <span class="cline-any cline-neutral">&nbsp;</span>
867
958
  <span class="cline-any cline-neutral">&nbsp;</span>
868
959
  <span class="cline-any cline-neutral">&nbsp;</span>
960
+ <span class="cline-any cline-yes">2x</span>
869
961
  <span class="cline-any cline-neutral">&nbsp;</span>
870
- <span class="cline-any cline-yes">1x</span>
871
- <span class="cline-any cline-yes">1x</span>
962
+ <span class="cline-any cline-yes">2x</span>
872
963
  <span class="cline-any cline-neutral">&nbsp;</span>
964
+ <span class="cline-any cline-yes">2x</span>
965
+ <span class="cline-any cline-yes">2x</span>
966
+ <span class="cline-any cline-yes">2x</span>
967
+ <span class="cline-any cline-yes">2x</span>
873
968
  <span class="cline-any cline-neutral">&nbsp;</span>
874
969
  <span class="cline-any cline-neutral">&nbsp;</span>
970
+ <span class="cline-any cline-yes">2x</span>
971
+ <span class="cline-any cline-yes">2x</span>
875
972
  <span class="cline-any cline-neutral">&nbsp;</span>
876
973
  <span class="cline-any cline-neutral">&nbsp;</span>
877
- <span class="cline-any cline-yes">1x</span>
878
- <span class="cline-any cline-yes">1x</span>
974
+ <span class="cline-any cline-yes">2x</span>
975
+ <span class="cline-any cline-yes">2x</span>
976
+ <span class="cline-any cline-yes">2x</span>
977
+ <span class="cline-any cline-yes">2x</span>
879
978
  <span class="cline-any cline-neutral">&nbsp;</span>
880
979
  <span class="cline-any cline-neutral">&nbsp;</span>
881
- <span class="cline-any cline-yes">1x</span>
882
- <span class="cline-any cline-yes">1x</span>
883
- <span class="cline-any cline-yes">1x</span>
884
- <span class="cline-any cline-yes">1x</span>
885
- <span class="cline-any cline-yes">1x</span>
886
- <span class="cline-any cline-yes">1x</span>
887
- <span class="cline-any cline-yes">1x</span>
888
- <span class="cline-any cline-yes">1x</span>
889
- <span class="cline-any cline-yes">1x</span>
890
- <span class="cline-any cline-yes">1x</span>
891
- <span class="cline-any cline-yes">1x</span>
892
- <span class="cline-any cline-yes">1x</span>
893
- <span class="cline-any cline-yes">1x</span>
894
- <span class="cline-any cline-yes">1x</span>
895
- <span class="cline-any cline-yes">1x</span>
980
+ <span class="cline-any cline-yes">2x</span>
981
+ <span class="cline-any cline-yes">2x</span>
982
+ <span class="cline-any cline-yes">2x</span>
983
+ <span class="cline-any cline-yes">2x</span>
984
+ <span class="cline-any cline-yes">2x</span>
985
+ <span class="cline-any cline-neutral">&nbsp;</span>
986
+ <span class="cline-any cline-yes">2x</span>
987
+ <span class="cline-any cline-neutral">&nbsp;</span>
896
988
  <span class="cline-any cline-neutral">&nbsp;</span>
897
989
  <span class="cline-any cline-neutral">&nbsp;</span>
898
990
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -946,37 +1038,52 @@
946
1038
  <span class="cline-any cline-neutral">&nbsp;</span>
947
1039
  <span class="cline-any cline-neutral">&nbsp;</span>
948
1040
  <span class="cline-any cline-neutral">&nbsp;</span>
1041
+ <span class="cline-any cline-yes">2x</span>
1042
+ <span class="cline-any cline-yes">108x</span>
1043
+ <span class="cline-any cline-yes">108x</span>
1044
+ <span class="cline-any cline-yes">108x</span>
1045
+ <span class="cline-any cline-neutral">&nbsp;</span>
1046
+ <span class="cline-any cline-neutral">&nbsp;</span>
1047
+ <span class="cline-any cline-yes">108x</span>
1048
+ <span class="cline-any cline-yes">108x</span>
1049
+ <span class="cline-any cline-yes">12x</span>
949
1050
  <span class="cline-any cline-yes">1x</span>
950
1051
  <span class="cline-any cline-neutral">&nbsp;</span>
951
1052
  <span class="cline-any cline-neutral">&nbsp;</span>
952
1053
  <span class="cline-any cline-neutral">&nbsp;</span>
953
1054
  <span class="cline-any cline-neutral">&nbsp;</span>
1055
+ <span class="cline-any cline-yes">108x</span>
954
1056
  <span class="cline-any cline-neutral">&nbsp;</span>
955
1057
  <span class="cline-any cline-neutral">&nbsp;</span>
1058
+ <span class="cline-any cline-yes">108x</span>
956
1059
  <span class="cline-any cline-neutral">&nbsp;</span>
957
1060
  <span class="cline-any cline-neutral">&nbsp;</span>
958
1061
  <span class="cline-any cline-neutral">&nbsp;</span>
959
1062
  <span class="cline-any cline-neutral">&nbsp;</span>
1063
+ <span class="cline-any cline-no">&nbsp;</span>
960
1064
  <span class="cline-any cline-neutral">&nbsp;</span>
961
1065
  <span class="cline-any cline-neutral">&nbsp;</span>
962
1066
  <span class="cline-any cline-neutral">&nbsp;</span>
1067
+ <span class="cline-any cline-yes">108x</span>
963
1068
  <span class="cline-any cline-neutral">&nbsp;</span>
964
1069
  <span class="cline-any cline-neutral">&nbsp;</span>
965
- <span class="cline-any cline-yes">130x</span>
966
1070
  <span class="cline-any cline-neutral">&nbsp;</span>
967
- <span class="cline-any cline-yes">130x</span>
968
- <span class="cline-any cline-yes">130x</span>
969
1071
  <span class="cline-any cline-neutral">&nbsp;</span>
1072
+ <span class="cline-any cline-no">&nbsp;</span>
970
1073
  <span class="cline-any cline-neutral">&nbsp;</span>
971
1074
  <span class="cline-any cline-neutral">&nbsp;</span>
972
1075
  <span class="cline-any cline-neutral">&nbsp;</span>
1076
+ <span class="cline-any cline-yes">108x</span>
1077
+ <span class="cline-any cline-yes">12x</span>
1078
+ <span class="cline-any cline-yes">1x</span>
973
1079
  <span class="cline-any cline-neutral">&nbsp;</span>
974
- <span class="cline-any cline-yes">130x</span>
975
1080
  <span class="cline-any cline-neutral">&nbsp;</span>
976
- <span class="cline-any cline-yes">54x</span>
977
1081
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
+ <span class="cline-any cline-yes">108x</span>
978
1083
  <span class="cline-any cline-neutral">&nbsp;</span>
1084
+ <span class="cline-any cline-no">&nbsp;</span>
979
1085
  <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-no">&nbsp;</span>
980
1087
  <span class="cline-any cline-neutral">&nbsp;</span>
981
1088
  <span class="cline-any cline-neutral">&nbsp;</span>
982
1089
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -984,110 +1091,128 @@
984
1091
  <span class="cline-any cline-neutral">&nbsp;</span>
985
1092
  <span class="cline-any cline-neutral">&nbsp;</span>
986
1093
  <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-no">&nbsp;</span>
987
1095
  <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-no">&nbsp;</span>
988
1097
  <span class="cline-any cline-neutral">&nbsp;</span>
989
1098
  <span class="cline-any cline-neutral">&nbsp;</span>
990
- <span class="cline-any cline-yes">54x</span>
991
- <span class="cline-any cline-yes">4x</span>
1099
+ <span class="cline-any cline-neutral">&nbsp;</span>
1100
+ <span class="cline-any cline-yes">2x</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-yes">199x</span>
1103
+ <span class="cline-any cline-neutral">&nbsp;</span>
1104
+ <span class="cline-any cline-yes">199x</span>
1105
+ <span class="cline-any cline-neutral">&nbsp;</span>
1106
+ <span class="cline-any cline-neutral">&nbsp;</span>
1107
+ <span class="cline-any cline-yes">199x</span>
992
1108
  <span class="cline-any cline-neutral">&nbsp;</span>
993
1109
  <span class="cline-any cline-neutral">&nbsp;</span>
994
1110
  <span class="cline-any cline-neutral">&nbsp;</span>
995
1111
  <span class="cline-any cline-neutral">&nbsp;</span>
1112
+ <span class="cline-any cline-yes">199x</span>
1113
+ <span class="cline-any cline-neutral">&nbsp;</span>
1114
+ <span class="cline-any cline-yes">85x</span>
1115
+ <span class="cline-any cline-neutral">&nbsp;</span>
1116
+ <span class="cline-any cline-neutral">&nbsp;</span>
1117
+ <span class="cline-any cline-neutral">&nbsp;</span>
1118
+ <span class="cline-any cline-neutral">&nbsp;</span>
1119
+ <span class="cline-any cline-yes">85x</span>
996
1120
  <span class="cline-any cline-yes">4x</span>
997
1121
  <span class="cline-any cline-neutral">&nbsp;</span>
1122
+ <span class="cline-any cline-neutral">&nbsp;</span>
1123
+ <span class="cline-any cline-neutral">&nbsp;</span>
1124
+ <span class="cline-any cline-neutral">&nbsp;</span>
1125
+ <span class="cline-any cline-neutral">&nbsp;</span>
998
1126
  <span class="cline-any cline-yes">4x</span>
999
1127
  <span class="cline-any cline-neutral">&nbsp;</span>
1000
1128
  <span class="cline-any cline-neutral">&nbsp;</span>
1129
+ <span class="cline-any cline-yes">4x</span>
1130
+ <span class="cline-any cline-yes">1x</span>
1001
1131
  <span class="cline-any cline-neutral">&nbsp;</span>
1002
1132
  <span class="cline-any cline-neutral">&nbsp;</span>
1003
1133
  <span class="cline-any cline-neutral">&nbsp;</span>
1004
1134
  <span class="cline-any cline-neutral">&nbsp;</span>
1005
- <span class="cline-any cline-yes">126x</span>
1006
1135
  <span class="cline-any cline-neutral">&nbsp;</span>
1007
- <span class="cline-any cline-yes">6x</span>
1008
- <span class="cline-any cline-yes">3x</span>
1136
+ <span class="cline-any cline-yes">1x</span>
1009
1137
  <span class="cline-any cline-neutral">&nbsp;</span>
1138
+ <span class="cline-any cline-yes">1x</span>
1010
1139
  <span class="cline-any cline-neutral">&nbsp;</span>
1140
+ <span class="cline-any cline-no">&nbsp;</span>
1011
1141
  <span class="cline-any cline-neutral">&nbsp;</span>
1012
1142
  <span class="cline-any cline-neutral">&nbsp;</span>
1013
1143
  <span class="cline-any cline-neutral">&nbsp;</span>
1014
1144
  <span class="cline-any cline-neutral">&nbsp;</span>
1015
- <span class="cline-any cline-yes">3x</span>
1016
1145
  <span class="cline-any cline-neutral">&nbsp;</span>
1017
- <span class="cline-any cline-yes">3x</span>
1018
1146
  <span class="cline-any cline-neutral">&nbsp;</span>
1019
1147
  <span class="cline-any cline-neutral">&nbsp;</span>
1020
1148
  <span class="cline-any cline-neutral">&nbsp;</span>
1021
- <span class="cline-any cline-yes">3x</span>
1022
- <span class="cline-any cline-yes">2x</span>
1149
+ <span class="cline-any cline-yes">1x</span>
1023
1150
  <span class="cline-any cline-neutral">&nbsp;</span>
1024
- <span class="cline-any cline-yes">2x</span>
1025
- <span class="cline-any cline-yes">2x</span>
1151
+ <span class="cline-any cline-no">&nbsp;</span>
1026
1152
  <span class="cline-any cline-neutral">&nbsp;</span>
1027
1153
  <span class="cline-any cline-neutral">&nbsp;</span>
1028
1154
  <span class="cline-any cline-neutral">&nbsp;</span>
1029
1155
  <span class="cline-any cline-neutral">&nbsp;</span>
1030
1156
  <span class="cline-any cline-neutral">&nbsp;</span>
1031
- <span class="cline-any cline-yes">2x</span>
1032
1157
  <span class="cline-any cline-neutral">&nbsp;</span>
1033
- <span class="cline-any cline-yes">2x</span>
1034
1158
  <span class="cline-any cline-neutral">&nbsp;</span>
1035
1159
  <span class="cline-any cline-neutral">&nbsp;</span>
1036
1160
  <span class="cline-any cline-neutral">&nbsp;</span>
1037
1161
  <span class="cline-any cline-neutral">&nbsp;</span>
1038
- <span class="cline-any cline-yes">1x</span>
1039
- <span class="cline-any cline-yes">1x</span>
1040
1162
  <span class="cline-any cline-neutral">&nbsp;</span>
1041
- <span class="cline-any cline-yes">1x</span>
1042
- <span class="cline-any cline-yes">1x</span>
1043
1163
  <span class="cline-any cline-neutral">&nbsp;</span>
1044
- <span class="cline-any cline-yes">1x</span>
1045
- <span class="cline-any cline-yes">1x</span>
1046
1164
  <span class="cline-any cline-neutral">&nbsp;</span>
1165
+ <span class="cline-any cline-yes">4x</span>
1166
+ <span class="cline-any cline-no">&nbsp;</span>
1047
1167
  <span class="cline-any cline-neutral">&nbsp;</span>
1048
1168
  <span class="cline-any cline-neutral">&nbsp;</span>
1049
1169
  <span class="cline-any cline-neutral">&nbsp;</span>
1050
1170
  <span class="cline-any cline-neutral">&nbsp;</span>
1051
1171
  <span class="cline-any cline-neutral">&nbsp;</span>
1052
- <span class="cline-any cline-yes">1x</span>
1053
1172
  <span class="cline-any cline-neutral">&nbsp;</span>
1054
- <span class="cline-any cline-yes">1x</span>
1055
1173
  <span class="cline-any cline-neutral">&nbsp;</span>
1056
1174
  <span class="cline-any cline-neutral">&nbsp;</span>
1175
+ <span class="cline-any cline-yes">4x</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-yes">4x</span>
1057
1178
  <span class="cline-any cline-neutral">&nbsp;</span>
1058
1179
  <span class="cline-any cline-neutral">&nbsp;</span>
1059
1180
  <span class="cline-any cline-neutral">&nbsp;</span>
1060
1181
  <span class="cline-any cline-neutral">&nbsp;</span>
1061
1182
  <span class="cline-any cline-neutral">&nbsp;</span>
1062
1183
  <span class="cline-any cline-neutral">&nbsp;</span>
1063
- <span class="cline-any cline-yes">120x</span>
1184
+ <span class="cline-any cline-yes">195x</span>
1064
1185
  <span class="cline-any cline-neutral">&nbsp;</span>
1186
+ <span class="cline-any cline-yes">7x</span>
1065
1187
  <span class="cline-any cline-yes">4x</span>
1066
- <span class="cline-any cline-yes">2x</span>
1067
1188
  <span class="cline-any cline-neutral">&nbsp;</span>
1068
1189
  <span class="cline-any cline-neutral">&nbsp;</span>
1069
1190
  <span class="cline-any cline-neutral">&nbsp;</span>
1070
1191
  <span class="cline-any cline-neutral">&nbsp;</span>
1071
1192
  <span class="cline-any cline-neutral">&nbsp;</span>
1072
1193
  <span class="cline-any cline-neutral">&nbsp;</span>
1073
- <span class="cline-any cline-yes">2x</span>
1074
1194
  <span class="cline-any cline-neutral">&nbsp;</span>
1075
- <span class="cline-any cline-yes">2x</span>
1195
+ <span class="cline-any cline-yes">4x</span>
1196
+ <span class="cline-any cline-neutral">&nbsp;</span>
1197
+ <span class="cline-any cline-yes">4x</span>
1076
1198
  <span class="cline-any cline-neutral">&nbsp;</span>
1077
1199
  <span class="cline-any cline-neutral">&nbsp;</span>
1078
1200
  <span class="cline-any cline-neutral">&nbsp;</span>
1201
+ <span class="cline-any cline-yes">3x</span>
1079
1202
  <span class="cline-any cline-yes">2x</span>
1080
- <span class="cline-any cline-yes">1x</span>
1081
1203
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
- <span class="cline-any cline-yes">1x</span>
1204
+ <span class="cline-any cline-yes">2x</span>
1205
+ <span class="cline-any cline-yes">2x</span>
1083
1206
  <span class="cline-any cline-neutral">&nbsp;</span>
1084
1207
  <span class="cline-any cline-neutral">&nbsp;</span>
1085
1208
  <span class="cline-any cline-neutral">&nbsp;</span>
1086
1209
  <span class="cline-any cline-neutral">&nbsp;</span>
1087
1210
  <span class="cline-any cline-neutral">&nbsp;</span>
1088
- <span class="cline-any cline-yes">1x</span>
1089
1211
  <span class="cline-any cline-neutral">&nbsp;</span>
1090
- <span class="cline-any cline-yes">1x</span>
1212
+ <span class="cline-any cline-yes">2x</span>
1213
+ <span class="cline-any cline-neutral">&nbsp;</span>
1214
+ <span class="cline-any cline-yes">2x</span>
1215
+ <span class="cline-any cline-neutral">&nbsp;</span>
1091
1216
  <span class="cline-any cline-neutral">&nbsp;</span>
1092
1217
  <span class="cline-any cline-neutral">&nbsp;</span>
1093
1218
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1096,6 +1221,8 @@
1096
1221
  <span class="cline-any cline-neutral">&nbsp;</span>
1097
1222
  <span class="cline-any cline-yes">1x</span>
1098
1223
  <span class="cline-any cline-yes">1x</span>
1224
+ <span class="cline-any cline-neutral">&nbsp;</span>
1225
+ <span class="cline-any cline-yes">1x</span>
1099
1226
  <span class="cline-any cline-yes">1x</span>
1100
1227
  <span class="cline-any cline-neutral">&nbsp;</span>
1101
1228
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1103,6 +1230,7 @@
1103
1230
  <span class="cline-any cline-neutral">&nbsp;</span>
1104
1231
  <span class="cline-any cline-neutral">&nbsp;</span>
1105
1232
  <span class="cline-any cline-neutral">&nbsp;</span>
1233
+ <span class="cline-any cline-neutral">&nbsp;</span>
1106
1234
  <span class="cline-any cline-yes">1x</span>
1107
1235
  <span class="cline-any cline-neutral">&nbsp;</span>
1108
1236
  <span class="cline-any cline-yes">1x</span>
@@ -1115,47 +1243,49 @@
1115
1243
  <span class="cline-any cline-neutral">&nbsp;</span>
1116
1244
  <span class="cline-any cline-neutral">&nbsp;</span>
1117
1245
  <span class="cline-any cline-neutral">&nbsp;</span>
1118
- <span class="cline-any cline-yes">116x</span>
1246
+ <span class="cline-any cline-yes">188x</span>
1119
1247
  <span class="cline-any cline-neutral">&nbsp;</span>
1120
1248
  <span class="cline-any cline-neutral">&nbsp;</span>
1121
- <span class="cline-any cline-yes">116x</span>
1122
- <span class="cline-any cline-yes">6x</span>
1249
+ <span class="cline-any cline-yes">188x</span>
1250
+ <span class="cline-any cline-yes">7x</span>
1251
+ <span class="cline-any cline-neutral">&nbsp;</span>
1123
1252
  <span class="cline-any cline-neutral">&nbsp;</span>
1124
1253
  <span class="cline-any cline-neutral">&nbsp;</span>
1125
1254
  <span class="cline-any cline-neutral">&nbsp;</span>
1126
1255
  <span class="cline-any cline-neutral">&nbsp;</span>
1127
- <span class="cline-any cline-yes">6x</span>
1256
+ <span class="cline-any cline-yes">7x</span>
1128
1257
  <span class="cline-any cline-neutral">&nbsp;</span>
1129
- <span class="cline-any cline-yes">6x</span>
1258
+ <span class="cline-any cline-yes">7x</span>
1130
1259
  <span class="cline-any cline-neutral">&nbsp;</span>
1131
1260
  <span class="cline-any cline-neutral">&nbsp;</span>
1132
1261
  <span class="cline-any cline-neutral">&nbsp;</span>
1133
- <span class="cline-any cline-yes">110x</span>
1262
+ <span class="cline-any cline-yes">181x</span>
1134
1263
  <span class="cline-any cline-yes">1x</span>
1135
1264
  <span class="cline-any cline-neutral">&nbsp;</span>
1136
1265
  <span class="cline-any cline-neutral">&nbsp;</span>
1137
1266
  <span class="cline-any cline-neutral">&nbsp;</span>
1138
1267
  <span class="cline-any cline-neutral">&nbsp;</span>
1139
1268
  <span class="cline-any cline-neutral">&nbsp;</span>
1140
- <span class="cline-any cline-yes">110x</span>
1141
- <span class="cline-any cline-yes">24x</span>
1142
- <span class="cline-any cline-yes">23x</span>
1269
+ <span class="cline-any cline-yes">181x</span>
1270
+ <span class="cline-any cline-yes">113x</span>
1271
+ <span class="cline-any cline-yes">111x</span>
1143
1272
  <span class="cline-any cline-neutral">&nbsp;</span>
1144
1273
  <span class="cline-any cline-neutral">&nbsp;</span>
1145
1274
  <span class="cline-any cline-neutral">&nbsp;</span>
1146
- <span class="cline-any cline-yes">24x</span>
1147
- <span class="cline-any cline-yes">1x</span>
1275
+ <span class="cline-any cline-yes">113x</span>
1276
+ <span class="cline-any cline-yes">2x</span>
1148
1277
  <span class="cline-any cline-neutral">&nbsp;</span>
1149
1278
  <span class="cline-any cline-neutral">&nbsp;</span>
1150
1279
  <span class="cline-any cline-neutral">&nbsp;</span>
1151
1280
  <span class="cline-any cline-neutral">&nbsp;</span>
1152
1281
  <span class="cline-any cline-neutral">&nbsp;</span>
1153
- <span class="cline-any cline-yes">1x</span>
1154
1282
  <span class="cline-any cline-neutral">&nbsp;</span>
1155
- <span class="cline-any cline-yes">1x</span>
1283
+ <span class="cline-any cline-yes">2x</span>
1284
+ <span class="cline-any cline-neutral">&nbsp;</span>
1285
+ <span class="cline-any cline-yes">2x</span>
1156
1286
  <span class="cline-any cline-neutral">&nbsp;</span>
1157
1287
  <span class="cline-any cline-neutral">&nbsp;</span>
1158
- <span class="cline-any cline-yes">23x</span>
1288
+ <span class="cline-any cline-yes">111x</span>
1159
1289
  <span class="cline-any cline-no">&nbsp;</span>
1160
1290
  <span class="cline-any cline-neutral">&nbsp;</span>
1161
1291
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1164,25 +1294,24 @@
1164
1294
  <span class="cline-any cline-neutral">&nbsp;</span>
1165
1295
  <span class="cline-any cline-neutral">&nbsp;</span>
1166
1296
  <span class="cline-any cline-neutral">&nbsp;</span>
1167
- <span class="cline-any cline-yes">109x</span>
1297
+ <span class="cline-any cline-yes">179x</span>
1168
1298
  <span class="cline-any cline-yes">1x</span>
1169
1299
  <span class="cline-any cline-neutral">&nbsp;</span>
1170
1300
  <span class="cline-any cline-neutral">&nbsp;</span>
1171
1301
  <span class="cline-any cline-neutral">&nbsp;</span>
1172
1302
  <span class="cline-any cline-neutral">&nbsp;</span>
1173
- <span class="cline-any cline-yes">1x</span>
1174
1303
  <span class="cline-any cline-neutral">&nbsp;</span>
1175
1304
  <span class="cline-any cline-yes">1x</span>
1176
1305
  <span class="cline-any cline-neutral">&nbsp;</span>
1306
+ <span class="cline-any cline-yes">1x</span>
1177
1307
  <span class="cline-any cline-neutral">&nbsp;</span>
1178
- <span class="cline-any cline-yes">108x</span>
1179
1308
  <span class="cline-any cline-neutral">&nbsp;</span>
1180
1309
  <span class="cline-any cline-neutral">&nbsp;</span>
1181
1310
  <span class="cline-any cline-neutral">&nbsp;</span>
1182
1311
  <span class="cline-any cline-neutral">&nbsp;</span>
1183
- <span class="cline-any cline-yes">108x</span>
1312
+ <span class="cline-any cline-yes">178x</span>
1184
1313
  <span class="cline-any cline-neutral">&nbsp;</span>
1185
- <span class="cline-any cline-yes">108x</span>
1314
+ <span class="cline-any cline-yes">178x</span>
1186
1315
  <span class="cline-any cline-neutral">&nbsp;</span>
1187
1316
  <span class="cline-any cline-yes">14x</span>
1188
1317
  <span class="cline-any cline-yes">9x</span>
@@ -1193,6 +1322,7 @@
1193
1322
  <span class="cline-any cline-neutral">&nbsp;</span>
1194
1323
  <span class="cline-any cline-neutral">&nbsp;</span>
1195
1324
  <span class="cline-any cline-neutral">&nbsp;</span>
1325
+ <span class="cline-any cline-neutral">&nbsp;</span>
1196
1326
  <span class="cline-any cline-yes">9x</span>
1197
1327
  <span class="cline-any cline-neutral">&nbsp;</span>
1198
1328
  <span class="cline-any cline-yes">9x</span>
@@ -1211,6 +1341,7 @@
1211
1341
  <span class="cline-any cline-neutral">&nbsp;</span>
1212
1342
  <span class="cline-any cline-neutral">&nbsp;</span>
1213
1343
  <span class="cline-any cline-neutral">&nbsp;</span>
1344
+ <span class="cline-any cline-neutral">&nbsp;</span>
1214
1345
  <span class="cline-any cline-yes">1x</span>
1215
1346
  <span class="cline-any cline-neutral">&nbsp;</span>
1216
1347
  <span class="cline-any cline-yes">1x</span>
@@ -1229,6 +1360,7 @@
1229
1360
  <span class="cline-any cline-neutral">&nbsp;</span>
1230
1361
  <span class="cline-any cline-neutral">&nbsp;</span>
1231
1362
  <span class="cline-any cline-neutral">&nbsp;</span>
1363
+ <span class="cline-any cline-neutral">&nbsp;</span>
1232
1364
  <span class="cline-any cline-yes">1x</span>
1233
1365
  <span class="cline-any cline-neutral">&nbsp;</span>
1234
1366
  <span class="cline-any cline-yes">1x</span>
@@ -1238,7 +1370,7 @@
1238
1370
  <span class="cline-any cline-neutral">&nbsp;</span>
1239
1371
  <span class="cline-any cline-neutral">&nbsp;</span>
1240
1372
  <span class="cline-any cline-neutral">&nbsp;</span>
1241
- <span class="cline-any cline-yes">97x</span>
1373
+ <span class="cline-any cline-yes">167x</span>
1242
1374
  <span class="cline-any cline-yes">4x</span>
1243
1375
  <span class="cline-any cline-neutral">&nbsp;</span>
1244
1376
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1255,21 +1387,34 @@
1255
1387
  <span class="cline-any cline-neutral">&nbsp;</span>
1256
1388
  <span class="cline-any cline-neutral">&nbsp;</span>
1257
1389
  <span class="cline-any cline-neutral">&nbsp;</span>
1390
+ <span class="cline-any cline-yes">4x</span>
1258
1391
  <span class="cline-any cline-neutral">&nbsp;</span>
1392
+ <span class="cline-any cline-yes">4x</span>
1393
+ <span class="cline-any cline-yes">1x</span>
1259
1394
  <span class="cline-any cline-neutral">&nbsp;</span>
1260
1395
  <span class="cline-any cline-neutral">&nbsp;</span>
1396
+ <span class="cline-any cline-yes">3x</span>
1397
+ <span class="cline-any cline-yes">2x</span>
1261
1398
  <span class="cline-any cline-neutral">&nbsp;</span>
1262
1399
  <span class="cline-any cline-neutral">&nbsp;</span>
1263
1400
  <span class="cline-any cline-neutral">&nbsp;</span>
1264
1401
  <span class="cline-any cline-neutral">&nbsp;</span>
1265
1402
  <span class="cline-any cline-neutral">&nbsp;</span>
1266
- <span class="cline-any cline-yes">4x</span>
1267
1403
  <span class="cline-any cline-neutral">&nbsp;</span>
1268
- <span class="cline-any cline-yes">4x</span>
1404
+ <span class="cline-any cline-neutral">&nbsp;</span>
1405
+ <span class="cline-any cline-yes">2x</span>
1406
+ <span class="cline-any cline-no">&nbsp;</span>
1407
+ <span class="cline-any cline-yes">2x</span>
1408
+ <span class="cline-any cline-yes">2x</span>
1409
+ <span class="cline-any cline-neutral">&nbsp;</span>
1410
+ <span class="cline-any cline-neutral">&nbsp;</span>
1411
+ <span class="cline-any cline-yes">2x</span>
1412
+ <span class="cline-any cline-neutral">&nbsp;</span>
1413
+ <span class="cline-any cline-neutral">&nbsp;</span>
1269
1414
  <span class="cline-any cline-yes">1x</span>
1270
1415
  <span class="cline-any cline-neutral">&nbsp;</span>
1271
1416
  <span class="cline-any cline-neutral">&nbsp;</span>
1272
- <span class="cline-any cline-yes">3x</span>
1417
+ <span class="cline-any cline-yes">4x</span>
1273
1418
  <span class="cline-any cline-yes">2x</span>
1274
1419
  <span class="cline-any cline-neutral">&nbsp;</span>
1275
1420
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1278,7 +1423,9 @@
1278
1423
  <span class="cline-any cline-neutral">&nbsp;</span>
1279
1424
  <span class="cline-any cline-neutral">&nbsp;</span>
1280
1425
  <span class="cline-any cline-neutral">&nbsp;</span>
1426
+ <span class="cline-any cline-yes">2x</span>
1281
1427
  <span class="cline-any cline-neutral">&nbsp;</span>
1428
+ <span class="cline-any cline-yes">2x</span>
1282
1429
  <span class="cline-any cline-neutral">&nbsp;</span>
1283
1430
  <span class="cline-any cline-neutral">&nbsp;</span>
1284
1431
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1286,28 +1433,29 @@
1286
1433
  <span class="cline-any cline-neutral">&nbsp;</span>
1287
1434
  <span class="cline-any cline-neutral">&nbsp;</span>
1288
1435
  <span class="cline-any cline-neutral">&nbsp;</span>
1289
- <span class="cline-any cline-yes">2x</span>
1290
- <span class="cline-any cline-no">&nbsp;</span>
1291
- <span class="cline-any cline-yes">2x</span>
1292
- <span class="cline-any cline-yes">2x</span>
1436
+ <span class="cline-any cline-yes">165x</span>
1293
1437
  <span class="cline-any cline-neutral">&nbsp;</span>
1294
1438
  <span class="cline-any cline-neutral">&nbsp;</span>
1295
- <span class="cline-any cline-yes">2x</span>
1296
1439
  <span class="cline-any cline-neutral">&nbsp;</span>
1297
1440
  <span class="cline-any cline-neutral">&nbsp;</span>
1298
- <span class="cline-any cline-yes">1x</span>
1299
1441
  <span class="cline-any cline-neutral">&nbsp;</span>
1300
1442
  <span class="cline-any cline-neutral">&nbsp;</span>
1301
- <span class="cline-any cline-yes">4x</span>
1302
- <span class="cline-any cline-yes">2x</span>
1443
+ <span class="cline-any cline-yes">165x</span>
1444
+ <span class="cline-any cline-yes">16x</span>
1445
+ <span class="cline-any cline-yes">10x</span>
1303
1446
  <span class="cline-any cline-neutral">&nbsp;</span>
1304
1447
  <span class="cline-any cline-neutral">&nbsp;</span>
1305
1448
  <span class="cline-any cline-neutral">&nbsp;</span>
1306
1449
  <span class="cline-any cline-neutral">&nbsp;</span>
1307
1450
  <span class="cline-any cline-neutral">&nbsp;</span>
1308
1451
  <span class="cline-any cline-neutral">&nbsp;</span>
1309
- <span class="cline-any cline-yes">2x</span>
1310
1452
  <span class="cline-any cline-neutral">&nbsp;</span>
1453
+ <span class="cline-any cline-neutral">&nbsp;</span>
1454
+ <span class="cline-any cline-neutral">&nbsp;</span>
1455
+ <span class="cline-any cline-yes">165x</span>
1456
+ <span class="cline-any cline-neutral">&nbsp;</span>
1457
+ <span class="cline-any cline-yes">165x</span>
1458
+ <span class="cline-any cline-yes">16x</span>
1311
1459
  <span class="cline-any cline-yes">2x</span>
1312
1460
  <span class="cline-any cline-neutral">&nbsp;</span>
1313
1461
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1315,20 +1463,28 @@
1315
1463
  <span class="cline-any cline-neutral">&nbsp;</span>
1316
1464
  <span class="cline-any cline-neutral">&nbsp;</span>
1317
1465
  <span class="cline-any cline-neutral">&nbsp;</span>
1318
- <span class="cline-any cline-yes">95x</span>
1319
1466
  <span class="cline-any cline-neutral">&nbsp;</span>
1320
1467
  <span class="cline-any cline-neutral">&nbsp;</span>
1321
1468
  <span class="cline-any cline-neutral">&nbsp;</span>
1322
1469
  <span class="cline-any cline-neutral">&nbsp;</span>
1323
1470
  <span class="cline-any cline-neutral">&nbsp;</span>
1471
+ <span class="cline-any cline-yes">165x</span>
1472
+ <span class="cline-any cline-yes">72x</span>
1473
+ <span class="cline-any cline-neutral">&nbsp;</span>
1474
+ <span class="cline-any cline-yes">72x</span>
1475
+ <span class="cline-any cline-yes">72x</span>
1476
+ <span class="cline-any cline-neutral">&nbsp;</span>
1324
1477
  <span class="cline-any cline-neutral">&nbsp;</span>
1478
+ <span class="cline-any cline-yes">93x</span>
1325
1479
  <span class="cline-any cline-neutral">&nbsp;</span>
1326
1480
  <span class="cline-any cline-neutral">&nbsp;</span>
1481
+ <span class="cline-any cline-yes">165x</span>
1482
+ <span class="cline-any cline-neutral">&nbsp;</span>
1483
+ <span class="cline-any cline-yes">161x</span>
1484
+ <span class="cline-any cline-yes">1x</span>
1327
1485
  <span class="cline-any cline-neutral">&nbsp;</span>
1328
1486
  <span class="cline-any cline-neutral">&nbsp;</span>
1329
1487
  <span class="cline-any cline-neutral">&nbsp;</span>
1330
- <span class="cline-any cline-yes">95x</span>
1331
- <span class="cline-any cline-yes">39x</span>
1332
1488
  <span class="cline-any cline-neutral">&nbsp;</span>
1333
1489
  <span class="cline-any cline-neutral">&nbsp;</span>
1334
1490
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1336,17 +1492,15 @@
1336
1492
  <span class="cline-any cline-neutral">&nbsp;</span>
1337
1493
  <span class="cline-any cline-neutral">&nbsp;</span>
1338
1494
  <span class="cline-any cline-neutral">&nbsp;</span>
1339
- <span class="cline-any cline-yes">39x</span>
1340
- <span class="cline-any cline-yes">39x</span>
1495
+ <span class="cline-any cline-yes">1x</span>
1341
1496
  <span class="cline-any cline-neutral">&nbsp;</span>
1342
- <span class="cline-any cline-yes">56x</span>
1497
+ <span class="cline-any cline-yes">1x</span>
1343
1498
  <span class="cline-any cline-neutral">&nbsp;</span>
1344
1499
  <span class="cline-any cline-neutral">&nbsp;</span>
1345
- <span class="cline-any cline-yes">95x</span>
1346
1500
  <span class="cline-any cline-neutral">&nbsp;</span>
1347
- <span class="cline-any cline-yes">90x</span>
1501
+ <span class="cline-any cline-yes">160x</span>
1348
1502
  <span class="cline-any cline-neutral">&nbsp;</span>
1349
- <span class="cline-any cline-yes">51x</span>
1503
+ <span class="cline-any cline-yes">88x</span>
1350
1504
  <span class="cline-any cline-yes">2x</span>
1351
1505
  <span class="cline-any cline-yes">2x</span>
1352
1506
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1364,6 +1518,7 @@
1364
1518
  <span class="cline-any cline-neutral">&nbsp;</span>
1365
1519
  <span class="cline-any cline-neutral">&nbsp;</span>
1366
1520
  <span class="cline-any cline-neutral">&nbsp;</span>
1521
+ <span class="cline-any cline-neutral">&nbsp;</span>
1367
1522
  <span class="cline-any cline-yes">1x</span>
1368
1523
  <span class="cline-any cline-neutral">&nbsp;</span>
1369
1524
  <span class="cline-any cline-yes">1x</span>
@@ -1378,13 +1533,14 @@
1378
1533
  <span class="cline-any cline-neutral">&nbsp;</span>
1379
1534
  <span class="cline-any cline-neutral">&nbsp;</span>
1380
1535
  <span class="cline-any cline-neutral">&nbsp;</span>
1536
+ <span class="cline-any cline-neutral">&nbsp;</span>
1381
1537
  <span class="cline-any cline-yes">1x</span>
1382
1538
  <span class="cline-any cline-neutral">&nbsp;</span>
1383
1539
  <span class="cline-any cline-yes">1x</span>
1384
1540
  <span class="cline-any cline-neutral">&nbsp;</span>
1385
1541
  <span class="cline-any cline-neutral">&nbsp;</span>
1386
1542
  <span class="cline-any cline-neutral">&nbsp;</span>
1387
- <span class="cline-any cline-yes">49x</span>
1543
+ <span class="cline-any cline-yes">86x</span>
1388
1544
  <span class="cline-any cline-yes">1x</span>
1389
1545
  <span class="cline-any cline-neutral">&nbsp;</span>
1390
1546
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1395,14 +1551,15 @@
1395
1551
  <span class="cline-any cline-neutral">&nbsp;</span>
1396
1552
  <span class="cline-any cline-neutral">&nbsp;</span>
1397
1553
  <span class="cline-any cline-neutral">&nbsp;</span>
1554
+ <span class="cline-any cline-neutral">&nbsp;</span>
1398
1555
  <span class="cline-any cline-yes">1x</span>
1399
1556
  <span class="cline-any cline-neutral">&nbsp;</span>
1400
1557
  <span class="cline-any cline-yes">1x</span>
1401
1558
  <span class="cline-any cline-neutral">&nbsp;</span>
1402
1559
  <span class="cline-any cline-neutral">&nbsp;</span>
1403
1560
  <span class="cline-any cline-neutral">&nbsp;</span>
1404
- <span class="cline-any cline-yes">48x</span>
1405
- <span class="cline-any cline-yes">48x</span>
1561
+ <span class="cline-any cline-yes">85x</span>
1562
+ <span class="cline-any cline-yes">85x</span>
1406
1563
  <span class="cline-any cline-neutral">&nbsp;</span>
1407
1564
  <span class="cline-any cline-neutral">&nbsp;</span>
1408
1565
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1412,21 +1569,21 @@
1412
1569
  <span class="cline-any cline-neutral">&nbsp;</span>
1413
1570
  <span class="cline-any cline-neutral">&nbsp;</span>
1414
1571
  <span class="cline-any cline-neutral">&nbsp;</span>
1415
- <span class="cline-any cline-yes">48x</span>
1416
1572
  <span class="cline-any cline-neutral">&nbsp;</span>
1417
- <span class="cline-any cline-yes">48x</span>
1573
+ <span class="cline-any cline-yes">85x</span>
1418
1574
  <span class="cline-any cline-neutral">&nbsp;</span>
1575
+ <span class="cline-any cline-yes">85x</span>
1419
1576
  <span class="cline-any cline-neutral">&nbsp;</span>
1420
1577
  <span class="cline-any cline-neutral">&nbsp;</span>
1421
1578
  <span class="cline-any cline-neutral">&nbsp;</span>
1422
- <span class="cline-any cline-yes">39x</span>
1423
1579
  <span class="cline-any cline-neutral">&nbsp;</span>
1424
- <span class="cline-any cline-yes">17x</span>
1425
- <span class="cline-any cline-yes">1x</span>
1580
+ <span class="cline-any cline-yes">72x</span>
1426
1581
  <span class="cline-any cline-neutral">&nbsp;</span>
1427
- <span class="cline-any cline-yes">1x</span>
1428
- <span class="cline-any cline-yes">1x</span>
1582
+ <span class="cline-any cline-yes">18x</span>
1583
+ <span class="cline-any cline-yes">3x</span>
1429
1584
  <span class="cline-any cline-neutral">&nbsp;</span>
1585
+ <span class="cline-any cline-yes">3x</span>
1586
+ <span class="cline-any cline-yes">3x</span>
1430
1587
  <span class="cline-any cline-neutral">&nbsp;</span>
1431
1588
  <span class="cline-any cline-neutral">&nbsp;</span>
1432
1589
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1435,20 +1592,20 @@
1435
1592
  <span class="cline-any cline-neutral">&nbsp;</span>
1436
1593
  <span class="cline-any cline-neutral">&nbsp;</span>
1437
1594
  <span class="cline-any cline-neutral">&nbsp;</span>
1438
- <span class="cline-any cline-yes">1x</span>
1439
1595
  <span class="cline-any cline-neutral">&nbsp;</span>
1440
- <span class="cline-any cline-yes">1x</span>
1441
1596
  <span class="cline-any cline-neutral">&nbsp;</span>
1597
+ <span class="cline-any cline-yes">3x</span>
1442
1598
  <span class="cline-any cline-neutral">&nbsp;</span>
1599
+ <span class="cline-any cline-yes">3x</span>
1443
1600
  <span class="cline-any cline-neutral">&nbsp;</span>
1444
1601
  <span class="cline-any cline-neutral">&nbsp;</span>
1445
- <span class="cline-any cline-yes">16x</span>
1446
- <span class="cline-any cline-yes">23x</span>
1447
1602
  <span class="cline-any cline-neutral">&nbsp;</span>
1448
- <span class="cline-any cline-yes">16x</span>
1449
- <span class="cline-any cline-yes">16x</span>
1450
1603
  <span class="cline-any cline-neutral">&nbsp;</span>
1604
+ <span class="cline-any cline-yes">15x</span>
1605
+ <span class="cline-any cline-yes">22x</span>
1451
1606
  <span class="cline-any cline-neutral">&nbsp;</span>
1607
+ <span class="cline-any cline-yes">15x</span>
1608
+ <span class="cline-any cline-yes">15x</span>
1452
1609
  <span class="cline-any cline-neutral">&nbsp;</span>
1453
1610
  <span class="cline-any cline-neutral">&nbsp;</span>
1454
1611
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1456,26 +1613,26 @@
1456
1613
  <span class="cline-any cline-neutral">&nbsp;</span>
1457
1614
  <span class="cline-any cline-neutral">&nbsp;</span>
1458
1615
  <span class="cline-any cline-neutral">&nbsp;</span>
1459
- <span class="cline-any cline-yes">16x</span>
1460
1616
  <span class="cline-any cline-neutral">&nbsp;</span>
1461
- <span class="cline-any cline-yes">16x</span>
1462
1617
  <span class="cline-any cline-neutral">&nbsp;</span>
1463
1618
  <span class="cline-any cline-neutral">&nbsp;</span>
1619
+ <span class="cline-any cline-yes">15x</span>
1464
1620
  <span class="cline-any cline-neutral">&nbsp;</span>
1621
+ <span class="cline-any cline-yes">15x</span>
1465
1622
  <span class="cline-any cline-neutral">&nbsp;</span>
1466
1623
  <span class="cline-any cline-neutral">&nbsp;</span>
1467
1624
  <span class="cline-any cline-neutral">&nbsp;</span>
1468
- <span class="cline-any cline-yes">27x</span>
1469
1625
  <span class="cline-any cline-neutral">&nbsp;</span>
1470
- <span class="cline-any cline-yes">22x</span>
1471
1626
  <span class="cline-any cline-neutral">&nbsp;</span>
1472
1627
  <span class="cline-any cline-neutral">&nbsp;</span>
1628
+ <span class="cline-any cline-yes">58x</span>
1473
1629
  <span class="cline-any cline-neutral">&nbsp;</span>
1630
+ <span class="cline-any cline-yes">54x</span>
1474
1631
  <span class="cline-any cline-neutral">&nbsp;</span>
1475
- <span class="cline-any cline-yes">2x</span>
1476
1632
  <span class="cline-any cline-neutral">&nbsp;</span>
1477
1633
  <span class="cline-any cline-neutral">&nbsp;</span>
1478
1634
  <span class="cline-any cline-neutral">&nbsp;</span>
1635
+ <span class="cline-any cline-yes">5x</span>
1479
1636
  <span class="cline-any cline-neutral">&nbsp;</span>
1480
1637
  <span class="cline-any cline-neutral">&nbsp;</span>
1481
1638
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1484,43 +1641,44 @@
1484
1641
  <span class="cline-any cline-neutral">&nbsp;</span>
1485
1642
  <span class="cline-any cline-neutral">&nbsp;</span>
1486
1643
  <span class="cline-any cline-neutral">&nbsp;</span>
1487
- <span class="cline-any cline-yes">2x</span>
1488
1644
  <span class="cline-any cline-neutral">&nbsp;</span>
1489
- <span class="cline-any cline-yes">2x</span>
1645
+ <span class="cline-any cline-neutral">&nbsp;</span>
1646
+ <span class="cline-any cline-neutral">&nbsp;</span>
1647
+ <span class="cline-any cline-neutral">&nbsp;</span>
1648
+ <span class="cline-any cline-yes">5x</span>
1649
+ <span class="cline-any cline-neutral">&nbsp;</span>
1650
+ <span class="cline-any cline-yes">5x</span>
1490
1651
  <span class="cline-any cline-neutral">&nbsp;</span>
1491
1652
  <span class="cline-any cline-neutral">&nbsp;</span>
1492
1653
  <span class="cline-any cline-neutral">&nbsp;</span>
1493
1654
  <span class="cline-any cline-neutral">&nbsp;</span>
1494
1655
  <span class="cline-any cline-neutral">&nbsp;</span>
1495
- <span class="cline-any cline-yes">20x</span>
1656
+ <span class="cline-any cline-yes">49x</span>
1496
1657
  <span class="cline-any cline-yes">3x</span>
1497
- <span class="cline-any cline-yes">17x</span>
1498
- <span class="cline-any cline-no">&nbsp;</span>
1499
- <span class="cline-any cline-yes">17x</span>
1500
- <span class="cline-any cline-yes">16x</span>
1658
+ <span class="cline-any cline-yes">46x</span>
1659
+ <span class="cline-any cline-yes">21x</span>
1660
+ <span class="cline-any cline-yes">25x</span>
1661
+ <span class="cline-any cline-yes">24x</span>
1501
1662
  <span class="cline-any cline-neutral">&nbsp;</span>
1502
1663
  <span class="cline-any cline-neutral">&nbsp;</span>
1503
- <span class="cline-any cline-yes">20x</span>
1504
- <span class="cline-any cline-yes">38x</span>
1664
+ <span class="cline-any cline-yes">49x</span>
1665
+ <span class="cline-any cline-yes">75x</span>
1505
1666
  <span class="cline-any cline-neutral">&nbsp;</span>
1506
- <span class="cline-any cline-yes">19x</span>
1507
- <span class="cline-any cline-yes">34x</span>
1667
+ <span class="cline-any cline-yes">48x</span>
1668
+ <span class="cline-any cline-yes">9x</span>
1508
1669
  <span class="cline-any cline-neutral">&nbsp;</span>
1509
- <span class="cline-any cline-yes">19x</span>
1510
- <span class="cline-any cline-yes">7x</span>
1670
+ <span class="cline-any cline-yes">9x</span>
1671
+ <span class="cline-any cline-yes">16x</span>
1511
1672
  <span class="cline-any cline-yes">7x</span>
1512
- <span class="cline-any cline-yes">12x</span>
1513
- <span class="cline-any cline-yes">5x</span>
1514
- <span class="cline-any cline-neutral">&nbsp;</span>
1515
1673
  <span class="cline-any cline-neutral">&nbsp;</span>
1516
1674
  <span class="cline-any cline-neutral">&nbsp;</span>
1517
1675
  <span class="cline-any cline-neutral">&nbsp;</span>
1518
1676
  <span class="cline-any cline-neutral">&nbsp;</span>
1519
1677
  <span class="cline-any cline-neutral">&nbsp;</span>
1520
- <span class="cline-any cline-yes">7x</span>
1521
- <span class="cline-any cline-yes">7x</span>
1522
1678
  <span class="cline-any cline-neutral">&nbsp;</span>
1523
1679
  <span class="cline-any cline-neutral">&nbsp;</span>
1680
+ <span class="cline-any cline-yes">9x</span>
1681
+ <span class="cline-any cline-yes">9x</span>
1524
1682
  <span class="cline-any cline-neutral">&nbsp;</span>
1525
1683
  <span class="cline-any cline-neutral">&nbsp;</span>
1526
1684
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1529,7 +1687,7 @@
1529
1687
  <span class="cline-any cline-no">&nbsp;</span>
1530
1688
  <span class="cline-any cline-neutral">&nbsp;</span>
1531
1689
  <span class="cline-any cline-neutral">&nbsp;</span>
1532
- <span class="cline-any cline-yes">7x</span>
1690
+ <span class="cline-any cline-yes">9x</span>
1533
1691
  <span class="cline-any cline-yes">4x</span>
1534
1692
  <span class="cline-any cline-neutral">&nbsp;</span>
1535
1693
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1542,18 +1700,19 @@
1542
1700
  <span class="cline-any cline-neutral">&nbsp;</span>
1543
1701
  <span class="cline-any cline-neutral">&nbsp;</span>
1544
1702
  <span class="cline-any cline-neutral">&nbsp;</span>
1703
+ <span class="cline-any cline-neutral">&nbsp;</span>
1545
1704
  <span class="cline-any cline-yes">4x</span>
1546
1705
  <span class="cline-any cline-neutral">&nbsp;</span>
1547
1706
  <span class="cline-any cline-yes">4x</span>
1548
1707
  <span class="cline-any cline-neutral">&nbsp;</span>
1549
1708
  <span class="cline-any cline-neutral">&nbsp;</span>
1550
1709
  <span class="cline-any cline-neutral">&nbsp;</span>
1551
- <span class="cline-any cline-yes">3x</span>
1552
- <span class="cline-any cline-yes">3x</span>
1710
+ <span class="cline-any cline-yes">44x</span>
1553
1711
  <span class="cline-any cline-neutral">&nbsp;</span>
1554
1712
  <span class="cline-any cline-neutral">&nbsp;</span>
1555
1713
  <span class="cline-any cline-neutral">&nbsp;</span>
1556
1714
  <span class="cline-any cline-neutral">&nbsp;</span>
1715
+ <span class="cline-any cline-yes">5x</span>
1557
1716
  <span class="cline-any cline-neutral">&nbsp;</span>
1558
1717
  <span class="cline-any cline-neutral">&nbsp;</span>
1559
1718
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1561,19 +1720,22 @@
1561
1720
  <span class="cline-any cline-neutral">&nbsp;</span>
1562
1721
  <span class="cline-any cline-neutral">&nbsp;</span>
1563
1722
  <span class="cline-any cline-neutral">&nbsp;</span>
1564
- <span class="cline-any cline-yes">3x</span>
1565
1723
  <span class="cline-any cline-neutral">&nbsp;</span>
1566
- <span class="cline-any cline-yes">3x</span>
1567
1724
  <span class="cline-any cline-neutral">&nbsp;</span>
1568
1725
  <span class="cline-any cline-neutral">&nbsp;</span>
1569
1726
  <span class="cline-any cline-neutral">&nbsp;</span>
1570
1727
  <span class="cline-any cline-neutral">&nbsp;</span>
1728
+ <span class="cline-any cline-yes">5x</span>
1571
1729
  <span class="cline-any cline-neutral">&nbsp;</span>
1730
+ <span class="cline-any cline-yes">5x</span>
1572
1731
  <span class="cline-any cline-neutral">&nbsp;</span>
1573
1732
  <span class="cline-any cline-neutral">&nbsp;</span>
1574
1733
  <span class="cline-any cline-neutral">&nbsp;</span>
1575
1734
  <span class="cline-any cline-neutral">&nbsp;</span>
1576
- <span class="cline-any cline-yes">18x</span>
1735
+ <span class="cline-any cline-neutral">&nbsp;</span>
1736
+ <span class="cline-any cline-neutral">&nbsp;</span>
1737
+ <span class="cline-any cline-neutral">&nbsp;</span>
1738
+ <span class="cline-any cline-yes">44x</span>
1577
1739
  <span class="cline-any cline-no">&nbsp;</span>
1578
1740
  <span class="cline-any cline-neutral">&nbsp;</span>
1579
1741
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1581,13 +1743,15 @@
1581
1743
  <span class="cline-any cline-neutral">&nbsp;</span>
1582
1744
  <span class="cline-any cline-neutral">&nbsp;</span>
1583
1745
  <span class="cline-any cline-neutral">&nbsp;</span>
1746
+ <span class="cline-any cline-neutral">&nbsp;</span>
1584
1747
  <span class="cline-any cline-no">&nbsp;</span>
1585
1748
  <span class="cline-any cline-neutral">&nbsp;</span>
1586
1749
  <span class="cline-any cline-no">&nbsp;</span>
1587
1750
  <span class="cline-any cline-neutral">&nbsp;</span>
1588
1751
  <span class="cline-any cline-neutral">&nbsp;</span>
1589
- <span class="cline-any cline-yes">18x</span>
1590
- <span class="cline-any cline-yes">13x</span>
1752
+ <span class="cline-any cline-yes">44x</span>
1753
+ <span class="cline-any cline-yes">40x</span>
1754
+ <span class="cline-any cline-yes">40x</span>
1591
1755
  <span class="cline-any cline-neutral">&nbsp;</span>
1592
1756
  <span class="cline-any cline-neutral">&nbsp;</span>
1593
1757
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1597,12 +1761,13 @@
1597
1761
  <span class="cline-any cline-neutral">&nbsp;</span>
1598
1762
  <span class="cline-any cline-neutral">&nbsp;</span>
1599
1763
  <span class="cline-any cline-neutral">&nbsp;</span>
1600
- <span class="cline-any cline-yes">13x</span>
1601
1764
  <span class="cline-any cline-neutral">&nbsp;</span>
1602
- <span class="cline-any cline-yes">13x</span>
1765
+ <span class="cline-any cline-yes">40x</span>
1603
1766
  <span class="cline-any cline-neutral">&nbsp;</span>
1767
+ <span class="cline-any cline-yes">40x</span>
1604
1768
  <span class="cline-any cline-neutral">&nbsp;</span>
1605
- <span class="cline-any cline-yes">5x</span>
1769
+ <span class="cline-any cline-neutral">&nbsp;</span>
1770
+ <span class="cline-any cline-no">&nbsp;</span>
1606
1771
  <span class="cline-any cline-neutral">&nbsp;</span>
1607
1772
  <span class="cline-any cline-neutral">&nbsp;</span>
1608
1773
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1610,13 +1775,30 @@
1610
1775
  <span class="cline-any cline-neutral">&nbsp;</span>
1611
1776
  <span class="cline-any cline-neutral">&nbsp;</span>
1612
1777
  <span class="cline-any cline-neutral">&nbsp;</span>
1613
- <span class="cline-any cline-yes">5x</span>
1614
1778
  <span class="cline-any cline-neutral">&nbsp;</span>
1615
- <span class="cline-any cline-yes">5x</span>
1779
+ <span class="cline-any cline-no">&nbsp;</span>
1616
1780
  <span class="cline-any cline-neutral">&nbsp;</span>
1617
1781
  <span class="cline-any cline-no">&nbsp;</span>
1618
1782
  <span class="cline-any cline-neutral">&nbsp;</span>
1619
1783
  <span class="cline-any cline-neutral">&nbsp;</span>
1784
+ <span class="cline-any cline-yes">4x</span>
1785
+ <span class="cline-any cline-neutral">&nbsp;</span>
1786
+ <span class="cline-any cline-neutral">&nbsp;</span>
1787
+ <span class="cline-any cline-neutral">&nbsp;</span>
1788
+ <span class="cline-any cline-neutral">&nbsp;</span>
1789
+ <span class="cline-any cline-neutral">&nbsp;</span>
1790
+ <span class="cline-any cline-neutral">&nbsp;</span>
1791
+ <span class="cline-any cline-neutral">&nbsp;</span>
1792
+ <span class="cline-any cline-neutral">&nbsp;</span>
1793
+ <span class="cline-any cline-yes">4x</span>
1794
+ <span class="cline-any cline-neutral">&nbsp;</span>
1795
+ <span class="cline-any cline-yes">4x</span>
1796
+ <span class="cline-any cline-neutral">&nbsp;</span>
1797
+ <span class="cline-any cline-no">&nbsp;</span>
1798
+ <span class="cline-any cline-neutral">&nbsp;</span>
1799
+ <span class="cline-any cline-neutral">&nbsp;</span>
1800
+ <span class="cline-any cline-neutral">&nbsp;</span>
1801
+ <span class="cline-any cline-neutral">&nbsp;</span>
1620
1802
  <span class="cline-any cline-neutral">&nbsp;</span>
1621
1803
  <span class="cline-any cline-neutral">&nbsp;</span>
1622
1804
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1625,8 +1807,7 @@
1625
1807
  <span class="cline-any cline-no">&nbsp;</span>
1626
1808
  <span class="cline-any cline-neutral">&nbsp;</span>
1627
1809
  <span class="cline-any cline-neutral">&nbsp;</span>
1628
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import {
1629
- Feature,
1810
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type {
1630
1811
  FeatureKey,
1631
1812
  Context,
1632
1813
  BucketKey,
@@ -1635,52 +1816,53 @@
1635
1816
  Traffic,
1636
1817
  Force,
1637
1818
  Required,
1638
- OverrideFeature,
1639
1819
  Variation,
1640
1820
  VariationValue,
1641
1821
  VariableKey,
1642
1822
  VariableValue,
1643
1823
  VariableSchema,
1824
+ EvaluatedFeature,
1644
1825
  StickyFeatures,
1645
- InitialFeatures,
1646
1826
  Allocation,
1647
1827
  } from "@featurevisor/types";
1648
1828
  &nbsp;
1649
1829
  import { Logger } from "./logger";
1830
+ import { HooksManager } from "./hooks";
1650
1831
  import { DatafileReader } from "./datafileReader";
1651
- import { getBucket, ConfigureBucketKey, ConfigureBucketValue } from "./bucket";
1652
- import {
1653
- getMatchedTraffic,
1654
- getMatchedTrafficAndAllocation,
1655
- findForceFromFeature,
1656
- parseFromStringifiedSegments,
1657
- } from "./feature";
1658
- import { allConditionsAreMatched } from "./conditions";
1659
- import { allGroupSegmentsAreMatched } from "./segments";
1660
- import type { Statuses, InterceptContext } from "./instance";
1832
+ import { getBucketKey, getBucketedNumber } from "./bucketer";
1661
1833
  &nbsp;
1662
1834
  export enum EvaluationReason {
1663
- NOT_FOUND = "not_found",
1664
- NO_VARIATIONS = "no_variations",
1665
- NO_MATCH = "no_match",
1666
- DISABLED = "disabled",
1667
- REQUIRED = "required",
1668
- OUT_OF_RANGE = "out_of_range",
1669
- FORCED = "forced",
1670
- INITIAL = "initial",
1671
- STICKY = "sticky",
1672
- RULE = "rule",
1673
- ALLOCATED = "allocated",
1674
- DEFAULTED = "defaulted",
1675
- OVERRIDE = "override",
1676
- ERROR = "error",
1835
+ // feature specific
1836
+ FEATURE_NOT_FOUND = "feature_not_found", // feature is not found in datafile
1837
+ DISABLED = "disabled", // feature is disabled
1838
+ REQUIRED = "required", // required features are not enabled
1839
+ OUT_OF_RANGE = "out_of_range", // out of range when mutually exclusive experiments are involved via Groups
1840
+ &nbsp;
1841
+ // variations specific
1842
+ NO_VARIATIONS = "no_variations", // feature has no variations
1843
+ VARIATION_DISABLED = "variation_disabled", // feature is disabled, and variation's disabledVariationValue is used
1844
+ &nbsp;
1845
+ // variable specific
1846
+ VARIABLE_NOT_FOUND = "variable_not_found", // variable's schema is not defined in the feature
1847
+ VARIABLE_DEFAULT = "variable_default", // default variable value used
1848
+ VARIABLE_DISABLED = "variable_disabled", // feature is disabled, and variable's disabledValue is used
1849
+ VARIABLE_OVERRIDE = "variable_override", // variable overridden from inside a variation
1850
+ &nbsp;
1851
+ // common
1852
+ NO_MATCH = "no_match", // no rules matched
1853
+ FORCED = "forced", // against a forced rule
1854
+ STICKY = "sticky", // against a sticky feature
1855
+ RULE = "rule", // against a regular rule
1856
+ ALLOCATED = "allocated", // regular allocation based on bucketing
1857
+ &nbsp;
1858
+ ERROR = "error", // error
1677
1859
  }
1678
1860
  &nbsp;
1679
1861
  type EvaluationType = "flag" | "variation" | "variable";
1680
1862
  &nbsp;
1681
1863
  export interface Evaluation {
1682
1864
  // required
1683
- // type: EvaluationType; // @TODO: bring in later
1865
+ type: EvaluationType;
1684
1866
  featureKey: FeatureKey;
1685
1867
  reason: EvaluationReason;
1686
1868
  &nbsp;
@@ -1694,8 +1876,7 @@ export interface Evaluation {
1694
1876
  forceIndex?: number;
1695
1877
  force?: Force;
1696
1878
  required?: Required[];
1697
- sticky?: OverrideFeature;
1698
- initial?: OverrideFeature;
1879
+ sticky?: EvaluatedFeature;
1699
1880
  &nbsp;
1700
1881
  // variation
1701
1882
  variation?: Variation;
@@ -1707,47 +1888,95 @@ export interface Evaluation {
1707
1888
  variableSchema?: VariableSchema;
1708
1889
  }
1709
1890
  &nbsp;
1710
- export interface EvaluateOptions {
1711
- type: EvaluationType;
1712
- &nbsp;
1713
- featureKey: FeatureKey | Feature;
1714
- variableKey?: VariableKey;
1891
+ export interface EvaluateDependencies {
1715
1892
  context: Context;
1716
1893
  &nbsp;
1717
1894
  logger: Logger;
1895
+ hooksManager: HooksManager;
1718
1896
  datafileReader: DatafileReader;
1719
- statuses?: Statuses;
1720
- interceptContext?: InterceptContext;
1721
1897
  &nbsp;
1722
- stickyFeatures?: StickyFeatures;
1723
- initialFeatures?: InitialFeatures;
1898
+ // OverrideOptions
1899
+ sticky?: StickyFeatures;
1724
1900
  &nbsp;
1725
- bucketKeySeparator?: string;
1726
- configureBucketKey?: ConfigureBucketKey;
1727
- configureBucketValue?: ConfigureBucketValue;
1901
+ defaultVariationValue?: VariationValue;
1902
+ defaultVariableValue?: VariableValue;
1903
+ }
1904
+ &nbsp;
1905
+ export interface EvaluateParams {
1906
+ type: EvaluationType;
1907
+ featureKey: FeatureKey;
1908
+ variableKey?: VariableKey;
1909
+ }
1910
+ &nbsp;
1911
+ export type EvaluateOptions = EvaluateParams &amp; EvaluateDependencies;
1912
+ &nbsp;
1913
+ export function evaluateWithHooks(opts: EvaluateOptions): Evaluation {
1914
+ try {
1915
+ const { hooksManager } = opts;
1916
+ const hooks = hooksManager.getAll();
1917
+ &nbsp;
1918
+ // run before hooks
1919
+ let options = opts;
1920
+ for (const hook of hooksManager.getAll()) {
1921
+ if (hook.before) {
1922
+ options = hook.before(options);
1923
+ }
1924
+ }
1925
+ &nbsp;
1926
+ // evaluate
1927
+ let evaluation = evaluate(options);
1928
+ &nbsp;
1929
+ // default: variation
1930
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (
1931
+ typeof options.defaultVariationValue !== "undefined" &amp;&amp;
1932
+ <span class="branch-1 cbranch-no" title="branch not covered" > evaluation.type === "variation" </span>&amp;&amp;
1933
+ <span class="branch-2 cbranch-no" title="branch not covered" > typeof evaluation.variationValue === "undefined"</span>
1934
+ ) {
1935
+ <span class="cstat-no" title="statement not covered" > evaluation.variationValue = options.defaultVariationValue;</span>
1936
+ }
1937
+ &nbsp;
1938
+ // default: variable
1939
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (
1940
+ typeof options.defaultVariableValue !== "undefined" &amp;&amp;
1941
+ <span class="branch-1 cbranch-no" title="branch not covered" > evaluation.type === "variable" </span>&amp;&amp;
1942
+ <span class="branch-2 cbranch-no" title="branch not covered" > typeof evaluation.variableValue === "undefined"</span>
1943
+ ) {
1944
+ <span class="cstat-no" title="statement not covered" > evaluation.variableValue = options.defaultVariableValue;</span>
1945
+ }
1946
+ &nbsp;
1947
+ // run after hooks
1948
+ for (const hook of hooks) {
1949
+ if (hook.after) {
1950
+ evaluation = hook.after(evaluation, options);
1951
+ }
1952
+ }
1953
+ &nbsp;
1954
+ return evaluation;
1955
+ } catch (e) {
1956
+ const { type, featureKey, variableKey, logger } = <span class="cstat-no" title="statement not covered" >opts;</span>
1957
+ &nbsp;
1958
+ const evaluation: Evaluation = <span class="cstat-no" title="statement not covered" >{</span>
1959
+ type,
1960
+ featureKey,
1961
+ variableKey,
1962
+ reason: EvaluationReason.ERROR,
1963
+ error: e,
1964
+ };
1965
+ &nbsp;
1966
+ <span class="cstat-no" title="statement not covered" > logger.error("error during evaluation", evaluation);</span>
1967
+ &nbsp;
1968
+ <span class="cstat-no" title="statement not covered" > return evaluation;</span>
1969
+ }
1728
1970
  }
1729
1971
  &nbsp;
1730
1972
  export function evaluate(options: EvaluateOptions): Evaluation {
1973
+ const { type, featureKey, variableKey, context, logger, datafileReader, sticky, hooksManager } =
1974
+ options;
1975
+ &nbsp;
1976
+ const hooks = hooksManager.getAll();
1731
1977
  let evaluation: Evaluation;
1732
- const {
1733
- type,
1734
- featureKey,
1735
- variableKey,
1736
- context,
1737
- logger,
1738
- datafileReader,
1739
- statuses,
1740
- stickyFeatures,
1741
- initialFeatures,
1742
- interceptContext,
1743
- bucketKeySeparator,
1744
- configureBucketKey,
1745
- configureBucketValue,
1746
- } = options;
1747
1978
  &nbsp;
1748
1979
  try {
1749
- const key = typeof featureKey === "string" ? featureKey : <span class="branch-1 cbranch-no" title="branch not covered" >featureKey.key;</span>
1750
- &nbsp;
1751
1980
  /**
1752
1981
  * Root flag evaluation
1753
1982
  */
@@ -1755,24 +1984,65 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1755
1984
  if (type !== "flag") {
1756
1985
  // needed by variation and variable evaluations
1757
1986
  flag = evaluate({
1987
+ ...options,
1758
1988
  type: "flag",
1759
- featureKey: key,
1760
- context,
1761
- logger,
1762
- datafileReader,
1763
- statuses,
1764
- stickyFeatures,
1765
- initialFeatures,
1766
- bucketKeySeparator,
1767
- configureBucketKey,
1768
- configureBucketValue,
1769
1989
  });
1770
1990
  &nbsp;
1771
1991
  if (flag.enabled === false) {
1772
1992
  evaluation = {
1773
- featureKey: key,
1993
+ type,
1994
+ featureKey,
1774
1995
  reason: EvaluationReason.DISABLED,
1775
1996
  };
1997
+ &nbsp;
1998
+ const feature = datafileReader.getFeature(featureKey);
1999
+ &nbsp;
2000
+ // serve variable default value if feature is disabled (if explicitly specified)
2001
+ if (type === "variable") {
2002
+ if (
2003
+ feature &amp;&amp;
2004
+ variableKey &amp;&amp;
2005
+ feature.variablesSchema &amp;&amp;
2006
+ feature.variablesSchema[variableKey]
2007
+ ) {
2008
+ const variableSchema = feature.variablesSchema[variableKey];
2009
+ &nbsp;
2010
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof variableSchema.disabledValue !== "undefined") {
2011
+ // disabledValue: &lt;value&gt;
2012
+ <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2013
+ type,
2014
+ featureKey,
2015
+ reason: EvaluationReason.VARIABLE_DISABLED,
2016
+ variableKey,
2017
+ variableValue: variableSchema.disabledValue,
2018
+ variableSchema,
2019
+ enabled: false,
2020
+ };
2021
+ } else <span class="missing-if-branch" title="if path not taken" >I</span>if (variableSchema.useDefaultWhenDisabled) {
2022
+ // useDefaultWhenDisabled: true
2023
+ <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2024
+ type,
2025
+ featureKey,
2026
+ reason: EvaluationReason.VARIABLE_DEFAULT,
2027
+ variableKey,
2028
+ variableValue: variableSchema.defaultValue,
2029
+ variableSchema,
2030
+ enabled: false,
2031
+ };
2032
+ }
2033
+ }
2034
+ }
2035
+ &nbsp;
2036
+ // serve disabled variation value if feature is disabled (if explicitly specified)
2037
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (type === "variation" &amp;&amp; feature &amp;&amp; feature.disabledVariationValue) {
2038
+ <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2039
+ type,
2040
+ featureKey,
2041
+ reason: EvaluationReason.VARIATION_DISABLED,
2042
+ variationValue: feature.disabledVariationValue,
2043
+ enabled: false,
2044
+ };
2045
+ }
1776
2046
  &nbsp;
1777
2047
  logger.debug("feature is disabled", evaluation);
1778
2048
  &nbsp;
@@ -1783,14 +2053,15 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1783
2053
  /**
1784
2054
  * Sticky
1785
2055
  */
1786
- if (stickyFeatures &amp;&amp; stickyFeatures[key]) {
2056
+ if (sticky &amp;&amp; sticky[featureKey]) {
1787
2057
  // flag
1788
- if (type === "flag" &amp;&amp; typeof stickyFeatures[key].enabled !== "undefined") {
2058
+ if (type === "flag" &amp;&amp; typeof sticky[featureKey].enabled !== "undefined") {
1789
2059
  evaluation = {
1790
- featureKey: key,
2060
+ type,
2061
+ featureKey,
1791
2062
  reason: EvaluationReason.STICKY,
1792
- sticky: stickyFeatures[key],
1793
- enabled: stickyFeatures[key].enabled,
2063
+ sticky: sticky[featureKey],
2064
+ enabled: sticky[featureKey].enabled,
1794
2065
  };
1795
2066
  &nbsp;
1796
2067
  logger.debug("using sticky enabled", evaluation);
@@ -1800,11 +2071,12 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1800
2071
  &nbsp;
1801
2072
  // variation
1802
2073
  if (type === "variation") {
1803
- const variationValue = stickyFeatures[key].variation;
2074
+ const variationValue = sticky[featureKey].variation;
1804
2075
  &nbsp;
1805
2076
  if (typeof variationValue !== "undefined") {
1806
2077
  evaluation = {
1807
- featureKey: key,
2078
+ type,
2079
+ featureKey,
1808
2080
  reason: EvaluationReason.STICKY,
1809
2081
  variationValue,
1810
2082
  };
@@ -1817,14 +2089,15 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1817
2089
  &nbsp;
1818
2090
  // variable
1819
2091
  if (variableKey) {
1820
- const variables = stickyFeatures[key].variables;
2092
+ const variables = sticky[featureKey].variables;
1821
2093
  &nbsp;
1822
2094
  if (variables) {
1823
2095
  const result = variables[variableKey];
1824
2096
  &nbsp;
1825
2097
  if (typeof result !== "undefined") {
1826
2098
  evaluation = {
1827
- featureKey: key,
2099
+ type,
2100
+ featureKey,
1828
2101
  reason: EvaluationReason.STICKY,
1829
2102
  variableKey,
1830
2103
  variableValue: result,
@@ -1837,60 +2110,6 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1837
2110
  }
1838
2111
  }
1839
2112
  }
1840
- &nbsp;
1841
- /**
1842
- * Initial
1843
- */
1844
- if (statuses &amp;&amp; !statuses.ready &amp;&amp; initialFeatures &amp;&amp; initialFeatures[key]) {
1845
- // flag
1846
- if (type === "flag" &amp;&amp; typeof initialFeatures[key].enabled !== "undefined") {
1847
- evaluation = {
1848
- featureKey: key,
1849
- reason: EvaluationReason.INITIAL,
1850
- initial: initialFeatures[key],
1851
- enabled: initialFeatures[key].enabled,
1852
- };
1853
- &nbsp;
1854
- logger.debug("using initial enabled", evaluation);
1855
- &nbsp;
1856
- return evaluation;
1857
- }
1858
- &nbsp;
1859
- // variation
1860
- if (type === "variation" &amp;&amp; typeof initialFeatures[key].variation !== "undefined") {
1861
- const variationValue = initialFeatures[key].variation;
1862
- &nbsp;
1863
- evaluation = {
1864
- featureKey: key,
1865
- reason: EvaluationReason.INITIAL,
1866
- variationValue,
1867
- };
1868
- &nbsp;
1869
- logger.debug("using initial variation", evaluation);
1870
- &nbsp;
1871
- return evaluation;
1872
- }
1873
- &nbsp;
1874
- // variable
1875
- if (variableKey) {
1876
- const variables = initialFeatures[key].variables;
1877
- &nbsp;
1878
- if (variables) {
1879
- if (typeof variables[variableKey] !== "undefined") {
1880
- evaluation = {
1881
- featureKey: key,
1882
- reason: EvaluationReason.INITIAL,
1883
- variableKey,
1884
- variableValue: variables[variableKey],
1885
- };
1886
- &nbsp;
1887
- logger.debug("using initial variable", evaluation);
1888
- &nbsp;
1889
- return evaluation;
1890
- }
1891
- }
1892
- }
1893
- }
1894
2113
  &nbsp;
1895
2114
  /**
1896
2115
  * Feature
@@ -1901,8 +2120,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1901
2120
  // feature: not found
1902
2121
  if (!feature) {
1903
2122
  evaluation = {
1904
- featureKey: key,
1905
- reason: EvaluationReason.NOT_FOUND, // @TODO: make it type-specific
2123
+ type,
2124
+ featureKey,
2125
+ reason: EvaluationReason.FEATURE_NOT_FOUND,
1906
2126
  };
1907
2127
  &nbsp;
1908
2128
  logger.warn("feature not found", evaluation);
@@ -1912,7 +2132,7 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1912
2132
  &nbsp;
1913
2133
  // feature: deprecated
1914
2134
  if (type === "flag" &amp;&amp; feature.deprecated) {
1915
- logger.warn("feature is deprecated", { featureKey: feature.key });
2135
+ logger.warn("feature is deprecated", { featureKey });
1916
2136
  }
1917
2137
  &nbsp;
1918
2138
  // variableSchema
@@ -1926,8 +2146,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1926
2146
  // variable schema not found
1927
2147
  if (!variableSchema) {
1928
2148
  evaluation = {
1929
- featureKey: key,
1930
- reason: EvaluationReason.NOT_FOUND,
2149
+ type,
2150
+ featureKey,
2151
+ reason: EvaluationReason.VARIABLE_NOT_FOUND,
1931
2152
  variableKey,
1932
2153
  };
1933
2154
  &nbsp;
@@ -1938,7 +2159,7 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1938
2159
  &nbsp;
1939
2160
  <span class="missing-if-branch" title="if path not taken" >I</span>if (variableSchema.deprecated) {
1940
2161
  <span class="cstat-no" title="statement not covered" > logger.warn("variable is deprecated", {</span>
1941
- featureKey: feature.key,
2162
+ featureKey,
1942
2163
  variableKey,
1943
2164
  });
1944
2165
  }
@@ -1947,7 +2168,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1947
2168
  // variation: no variations
1948
2169
  if (type === "variation" &amp;&amp; (!feature.variations || feature.variations.length === 0)) {
1949
2170
  evaluation = {
1950
- featureKey: key,
2171
+ type,
2172
+ featureKey,
1951
2173
  reason: EvaluationReason.NO_VARIATIONS,
1952
2174
  };
1953
2175
  &nbsp;
@@ -1955,19 +2177,18 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1955
2177
  &nbsp;
1956
2178
  return evaluation;
1957
2179
  }
1958
- &nbsp;
1959
- const finalContext = interceptContext ? interceptContext(context) : context;
1960
2180
  &nbsp;
1961
2181
  /**
1962
2182
  * Forced
1963
2183
  */
1964
- const { force, forceIndex } = findForceFromFeature(feature, context, datafileReader, logger);
2184
+ const { force, forceIndex } = datafileReader.getMatchedForce(feature, context);
1965
2185
  &nbsp;
1966
2186
  if (force) {
1967
2187
  // flag
1968
2188
  if (type === "flag" &amp;&amp; typeof force.enabled !== "undefined") {
1969
2189
  evaluation = {
1970
- featureKey: feature.key,
2190
+ type,
2191
+ featureKey,
1971
2192
  reason: EvaluationReason.FORCED,
1972
2193
  forceIndex,
1973
2194
  force,
@@ -1985,7 +2206,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
1985
2206
  &nbsp;
1986
2207
  if (variation) {
1987
2208
  evaluation = {
1988
- featureKey: feature.key,
2209
+ type,
2210
+ featureKey,
1989
2211
  reason: EvaluationReason.FORCED,
1990
2212
  forceIndex,
1991
2213
  force,
@@ -2001,7 +2223,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2001
2223
  // variable
2002
2224
  if (variableKey &amp;&amp; force.variables &amp;&amp; typeof force.variables[variableKey] !== "undefined") {
2003
2225
  evaluation = {
2004
- featureKey: feature.key,
2226
+ type,
2227
+ featureKey,
2005
2228
  reason: EvaluationReason.FORCED,
2006
2229
  forceIndex,
2007
2230
  force,
@@ -2032,17 +2255,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2032
2255
  }
2033
2256
  &nbsp;
2034
2257
  const requiredEvaluation = evaluate({
2258
+ ...options,
2035
2259
  type: "flag",
2036
2260
  featureKey: requiredKey,
2037
- context: finalContext,
2038
- logger,
2039
- datafileReader,
2040
- statuses,
2041
- stickyFeatures,
2042
- initialFeatures,
2043
- bucketKeySeparator,
2044
- configureBucketKey,
2045
- configureBucketValue,
2046
2261
  });
2047
2262
  const requiredIsEnabled = requiredEvaluation.enabled;
2048
2263
  &nbsp;
@@ -2052,17 +2267,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2052
2267
  &nbsp;
2053
2268
  if (typeof requiredVariation !== "undefined") {
2054
2269
  const requiredVariationEvaluation = evaluate({
2270
+ ...options,
2055
2271
  type: "variation",
2056
2272
  featureKey: requiredKey,
2057
- context: finalContext,
2058
- logger,
2059
- datafileReader,
2060
- statuses,
2061
- stickyFeatures,
2062
- initialFeatures,
2063
- bucketKeySeparator,
2064
- configureBucketKey,
2065
- configureBucketValue,
2066
2273
  });
2067
2274
  &nbsp;
2068
2275
  let requiredVariationValue;
@@ -2081,7 +2288,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2081
2288
  &nbsp;
2082
2289
  if (!requiredFeaturesAreEnabled) {
2083
2290
  evaluation = {
2084
- featureKey: feature.key,
2291
+ type,
2292
+ featureKey,
2085
2293
  reason: EvaluationReason.REQUIRED,
2086
2294
  required: feature.required,
2087
2295
  enabled: requiredFeaturesAreEnabled,
@@ -2096,34 +2304,71 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2096
2304
  /**
2097
2305
  * Bucketing
2098
2306
  */
2099
- const { bucketKey, bucketValue } = getBucket({
2100
- feature,
2101
- context: finalContext,
2307
+ // bucketKey
2308
+ let bucketKey = getBucketKey({
2309
+ featureKey,
2310
+ bucketBy: feature.bucketBy,
2311
+ context,
2312
+ &nbsp;
2102
2313
  logger,
2103
- bucketKeySeparator,
2104
- configureBucketKey,
2105
- configureBucketValue,
2106
2314
  });
2315
+ for (const hook of hooks) {
2316
+ if (hook.bucketKey) {
2317
+ bucketKey = hook.bucketKey({
2318
+ featureKey,
2319
+ context,
2320
+ bucketBy: feature.bucketBy,
2321
+ bucketKey,
2322
+ });
2323
+ }
2324
+ }
2325
+ &nbsp;
2326
+ // bucketValue
2327
+ let bucketValue = getBucketedNumber(bucketKey);
2328
+ &nbsp;
2329
+ for (const hook of hooks) {
2330
+ if (hook.bucketValue) {
2331
+ bucketValue = hook.bucketValue({
2332
+ featureKey,
2333
+ bucketKey,
2334
+ context,
2335
+ bucketValue,
2336
+ });
2337
+ }
2338
+ }
2107
2339
  &nbsp;
2108
2340
  let matchedTraffic: Traffic | undefined;
2109
2341
  let matchedAllocation: Allocation | undefined;
2110
2342
  &nbsp;
2111
2343
  if (type !== "flag") {
2112
- const matched = getMatchedTrafficAndAllocation(
2113
- feature.traffic,
2114
- finalContext,
2115
- bucketValue,
2116
- datafileReader,
2117
- logger,
2118
- );
2344
+ matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);
2119
2345
  &nbsp;
2120
- matchedTraffic = matched.matchedTraffic;
2121
- matchedAllocation = matched.matchedAllocation;
2346
+ if (matchedTraffic) {
2347
+ matchedAllocation = datafileReader.getMatchedAllocation(matchedTraffic, bucketValue);
2348
+ }
2122
2349
  } else {
2123
- matchedTraffic = getMatchedTraffic(feature.traffic, finalContext, datafileReader, logger);
2350
+ matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);
2124
2351
  }
2125
2352
  &nbsp;
2126
2353
  if (matchedTraffic) {
2354
+ // percentage: 0
2355
+ if (matchedTraffic.percentage === 0) {
2356
+ evaluation = {
2357
+ type,
2358
+ featureKey,
2359
+ reason: EvaluationReason.RULE,
2360
+ bucketKey,
2361
+ bucketValue,
2362
+ ruleKey: matchedTraffic.key,
2363
+ traffic: matchedTraffic,
2364
+ enabled: false,
2365
+ };
2366
+ &nbsp;
2367
+ logger.debug("matched rule with 0 percentage", evaluation);
2368
+ &nbsp;
2369
+ return evaluation;
2370
+ }
2371
+ &nbsp;
2127
2372
  // flag
2128
2373
  if (type === "flag") {
2129
2374
  // flag: check if mutually exclusive
@@ -2135,7 +2380,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2135
2380
  // matched
2136
2381
  if (matchedRange) {
2137
2382
  evaluation = {
2138
- featureKey: feature.key,
2383
+ type,
2384
+ featureKey,
2139
2385
  reason: EvaluationReason.ALLOCATED,
2140
2386
  bucketKey,
2141
2387
  bucketValue,
@@ -2152,7 +2398,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2152
2398
  &nbsp;
2153
2399
  // no match
2154
2400
  evaluation = {
2155
- featureKey: feature.key,
2401
+ type,
2402
+ featureKey,
2156
2403
  reason: EvaluationReason.OUT_OF_RANGE,
2157
2404
  bucketKey,
2158
2405
  bucketValue,
@@ -2167,8 +2414,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2167
2414
  // flag: override from rule
2168
2415
  if (typeof matchedTraffic.enabled !== "undefined") {
2169
2416
  evaluation = {
2170
- featureKey: feature.key,
2171
- reason: EvaluationReason.OVERRIDE,
2417
+ type,
2418
+ featureKey,
2419
+ reason: EvaluationReason.RULE,
2172
2420
  bucketKey,
2173
2421
  bucketValue,
2174
2422
  ruleKey: matchedTraffic.key,
@@ -2184,7 +2432,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2184
2432
  // treated as enabled because of matched traffic
2185
2433
  if (bucketValue &lt;= matchedTraffic.percentage) {
2186
2434
  evaluation = {
2187
- featureKey: feature.key,
2435
+ type,
2436
+ featureKey,
2188
2437
  reason: EvaluationReason.RULE,
2189
2438
  bucketKey,
2190
2439
  bucketValue,
@@ -2207,7 +2456,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2207
2456
  &nbsp;
2208
2457
  if (variation) {
2209
2458
  evaluation = {
2210
- featureKey: feature.key,
2459
+ type,
2460
+ featureKey,
2211
2461
  reason: EvaluationReason.RULE,
2212
2462
  bucketKey,
2213
2463
  bucketValue,
@@ -2228,7 +2478,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2228
2478
  &nbsp;
2229
2479
  if (variation) {
2230
2480
  evaluation = {
2231
- featureKey: feature.key,
2481
+ type,
2482
+ featureKey,
2232
2483
  reason: EvaluationReason.ALLOCATED,
2233
2484
  bucketKey,
2234
2485
  bucketValue,
@@ -2254,7 +2505,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2254
2505
  typeof matchedTraffic.variables[variableKey] !== "undefined"
2255
2506
  ) {
2256
2507
  evaluation = {
2257
- featureKey: feature.key,
2508
+ type,
2509
+ featureKey,
2258
2510
  reason: EvaluationReason.RULE,
2259
2511
  bucketKey,
2260
2512
  bucketValue,
@@ -2275,8 +2527,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2275
2527
  &nbsp;
2276
2528
  if (force &amp;&amp; force.variation) {
2277
2529
  variationValue = force.variation;
2278
- } else <span class="missing-if-branch" title="if path not taken" >I</span>if (matchedTraffic &amp;&amp; matchedTraffic.variation) {
2279
- <span class="cstat-no" title="statement not covered" > variationValue = matchedTraffic.variation;</span>
2530
+ } else if (matchedTraffic &amp;&amp; matchedTraffic.variation) {
2531
+ variationValue = matchedTraffic.variation;
2280
2532
  } else if (matchedAllocation &amp;&amp; matchedAllocation.variation) {
2281
2533
  variationValue = matchedAllocation.variation;
2282
2534
  }
@@ -2284,70 +2536,71 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2284
2536
  if (variationValue &amp;&amp; Array.isArray(feature.variations)) {
2285
2537
  const variation = feature.variations.find((v) =&gt; v.value === variationValue);
2286
2538
  &nbsp;
2287
- if (variation &amp;&amp; variation.variables) {
2288
- const variableFromVariation = variation.variables.find((v) =&gt; v.key === variableKey);
2289
- &nbsp;
2290
- if (variableFromVariation) {
2291
- if (variableFromVariation.overrides) {
2292
- const override = variableFromVariation.overrides.find((o) =&gt; {
2293
- if (o.conditions) {
2294
- return allConditionsAreMatched(
2295
- typeof o.conditions === "string" ? <span class="branch-0 cbranch-no" title="branch not covered" >JSON.parse(o.conditions) </span>: o.conditions,
2296
- finalContext,
2297
- logger,
2298
- );
2299
- }
2300
- &nbsp;
2301
- if (o.segments) {
2302
- return allGroupSegmentsAreMatched(
2303
- parseFromStringifiedSegments(o.segments),
2304
- finalContext,
2305
- datafileReader,
2306
- logger,
2307
- );
2308
- }
2309
- &nbsp;
2310
- <span class="cstat-no" title="statement not covered" > return false;</span>
2311
- });
2312
- &nbsp;
2313
- if (override) {
2314
- evaluation = {
2315
- featureKey: feature.key,
2316
- reason: EvaluationReason.OVERRIDE,
2317
- bucketKey,
2318
- bucketValue,
2319
- ruleKey: matchedTraffic<span class="branch-0 cbranch-no" title="branch not covered" >?.k</span>ey,
2320
- traffic: matchedTraffic,
2321
- variableKey,
2322
- variableSchema,
2323
- variableValue: override.value,
2324
- };
2325
- &nbsp;
2326
- logger.debug("variable override", evaluation);
2327
- &nbsp;
2328
- return evaluation;
2329
- }
2539
+ if (variation &amp;&amp; variation.variableOverrides &amp;&amp; variation.variableOverrides[variableKey]) {
2540
+ const overrides = variation.variableOverrides[variableKey];
2541
+ &nbsp;
2542
+ const override = overrides.find((o) =&gt; {
2543
+ if (o.conditions) {
2544
+ return datafileReader.allConditionsAreMatched(
2545
+ typeof o.conditions === "string" &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >o.conditions !== "*"</span>
2546
+ ? <span class="branch-0 cbranch-no" title="branch not covered" >JSON.parse(o.conditions)</span>
2547
+ : o.conditions,
2548
+ context,
2549
+ );
2330
2550
  }
2331
2551
  &nbsp;
2332
- if (typeof variableFromVariation.value !== "undefined") {
2333
- evaluation = {
2334
- featureKey: feature.key,
2335
- reason: EvaluationReason.ALLOCATED,
2336
- bucketKey,
2337
- bucketValue,
2338
- ruleKey: matchedTraffic<span class="branch-0 cbranch-no" title="branch not covered" >?.k</span>ey,
2339
- traffic: matchedTraffic,
2340
- variableKey,
2341
- variableSchema,
2342
- variableValue: variableFromVariation.value,
2343
- };
2552
+ if (o.segments) {
2553
+ return datafileReader.allSegmentsAreMatched(
2554
+ datafileReader.parseSegmentsIfStringified(o.segments),
2555
+ context,
2556
+ );
2557
+ }
2344
2558
  &nbsp;
2345
- logger.debug("allocated variable", evaluation);
2559
+ <span class="cstat-no" title="statement not covered" > return false;</span>
2560
+ });
2346
2561
  &nbsp;
2347
- return evaluation;
2348
- }
2562
+ if (override) {
2563
+ evaluation = {
2564
+ type,
2565
+ featureKey,
2566
+ reason: EvaluationReason.VARIABLE_OVERRIDE,
2567
+ bucketKey,
2568
+ bucketValue,
2569
+ ruleKey: matchedTraffic<span class="branch-0 cbranch-no" title="branch not covered" >?.k</span>ey,
2570
+ traffic: matchedTraffic,
2571
+ variableKey,
2572
+ variableSchema,
2573
+ variableValue: override.value,
2574
+ };
2575
+ &nbsp;
2576
+ logger.debug("variable override", evaluation);
2577
+ &nbsp;
2578
+ return evaluation;
2349
2579
  }
2350
2580
  }
2581
+ &nbsp;
2582
+ if (
2583
+ variation &amp;&amp;
2584
+ variation.variables &amp;&amp;
2585
+ typeof variation.variables[variableKey] !== "undefined"
2586
+ ) {
2587
+ evaluation = {
2588
+ type,
2589
+ featureKey,
2590
+ reason: EvaluationReason.ALLOCATED,
2591
+ bucketKey,
2592
+ bucketValue,
2593
+ ruleKey: matchedTraffic<span class="branch-0 cbranch-no" title="branch not covered" >?.k</span>ey,
2594
+ traffic: matchedTraffic,
2595
+ variableKey,
2596
+ variableSchema,
2597
+ variableValue: variation.variables[variableKey],
2598
+ };
2599
+ &nbsp;
2600
+ logger.debug("allocated variable", evaluation);
2601
+ &nbsp;
2602
+ return evaluation;
2603
+ }
2351
2604
  }
2352
2605
  }
2353
2606
  &nbsp;
@@ -2356,7 +2609,8 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2356
2609
  */
2357
2610
  <span class="missing-if-branch" title="if path not taken" >I</span>if (type === "variation") {
2358
2611
  <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2359
- featureKey: feature.key,
2612
+ type,
2613
+ featureKey,
2360
2614
  reason: EvaluationReason.NO_MATCH,
2361
2615
  bucketKey,
2362
2616
  bucketValue,
@@ -2367,24 +2621,41 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2367
2621
  <span class="cstat-no" title="statement not covered" > return evaluation;</span>
2368
2622
  }
2369
2623
  &nbsp;
2370
- if (type === "variable" &amp;&amp; variableSchema) {
2371
- evaluation = {
2372
- featureKey: feature.key,
2373
- reason: EvaluationReason.DEFAULTED,
2624
+ if (type === "variable") {
2625
+ if (variableSchema) {
2626
+ evaluation = {
2627
+ type,
2628
+ featureKey,
2629
+ reason: EvaluationReason.VARIABLE_DEFAULT,
2630
+ bucketKey,
2631
+ bucketValue,
2632
+ variableKey,
2633
+ variableSchema,
2634
+ variableValue: variableSchema.defaultValue,
2635
+ };
2636
+ &nbsp;
2637
+ logger.debug("using default value", evaluation);
2638
+ &nbsp;
2639
+ return evaluation;
2640
+ }
2641
+ &nbsp;
2642
+ <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2643
+ type,
2644
+ featureKey,
2645
+ reason: EvaluationReason.VARIABLE_NOT_FOUND,
2646
+ variableKey,
2374
2647
  bucketKey,
2375
2648
  bucketValue,
2376
- variableKey,
2377
- variableSchema,
2378
- variableValue: variableSchema.defaultValue,
2379
2649
  };
2380
2650
  &nbsp;
2381
- logger.debug("using default value", evaluation);
2651
+ <span class="cstat-no" title="statement not covered" > logger.debug("variable not found", evaluation);</span>
2382
2652
  &nbsp;
2383
- return evaluation;
2653
+ <span class="cstat-no" title="statement not covered" > return evaluation;</span>
2384
2654
  }
2385
2655
  &nbsp;
2386
2656
  evaluation = {
2387
- featureKey: feature.key,
2657
+ type,
2658
+ featureKey,
2388
2659
  reason: EvaluationReason.NO_MATCH,
2389
2660
  bucketKey,
2390
2661
  bucketValue,
@@ -2396,7 +2667,9 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2396
2667
  return evaluation;
2397
2668
  } catch (e) {
2398
2669
  <span class="cstat-no" title="statement not covered" > evaluation = {</span>
2399
- featureKey: typeof featureKey === "string" ? featureKey : featureKey.key,
2670
+ type,
2671
+ featureKey,
2672
+ variableKey,
2400
2673
  reason: EvaluationReason.ERROR,
2401
2674
  error: e,
2402
2675
  };
@@ -2413,7 +2686,7 @@ export function evaluate(options: EvaluateOptions): Evaluation {
2413
2686
  <div class='footer quiet pad2 space-top1 center small'>
2414
2687
  Code coverage generated by
2415
2688
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2416
- at 2025-03-31T21:26:29.644Z
2689
+ at 2025-07-13T22:31:55.309Z
2417
2690
  </div>
2418
2691
  <script src="prettify.js"></script>
2419
2692
  <script>