ts-fsrs 5.2.3 → 5.3.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.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +110 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.mjs +110 -192
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +110 -191
- package/dist/index.umd.js.map +1 -1
- package/package.json +25 -36
- package/README.md +0 -174
package/dist/index.d.ts
CHANGED
|
@@ -325,9 +325,10 @@ declare class FSRSAlgorithm {
|
|
|
325
325
|
* @param memory_state - The current state of memory, which can be null.
|
|
326
326
|
* @param t - The time elapsed since the last review.
|
|
327
327
|
* @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])
|
|
328
|
+
* @param r - Optional retrievability value. If not provided, it will be calculated.
|
|
328
329
|
* @returns The next state of memory with updated difficulty and stability.
|
|
329
330
|
*/
|
|
330
|
-
next_state(memory_state: FSRSState | null, t: number, g: number): FSRSState;
|
|
331
|
+
next_state(memory_state: FSRSState | null, t: number, g: number, r?: number): FSRSState;
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
declare enum StrategyMode {
|
|
@@ -409,7 +410,7 @@ declare const clipParameters: (parameters: number[], numRelearningSteps: number,
|
|
|
409
410
|
* alert(e);
|
|
410
411
|
* }
|
|
411
412
|
*/
|
|
412
|
-
declare const checkParameters: (parameters: number[] | readonly number[]) => number[] |
|
|
413
|
+
declare const checkParameters: (parameters: number[] | readonly number[]) => readonly number[] | number[];
|
|
413
414
|
declare const migrateParameters: (parameters?: number[] | readonly number[], numRelearningSteps?: number, enableShortTerm?: boolean) => number[];
|
|
414
415
|
declare const generatorParameters: (props?: Partial<FSRSParameters>) => FSRSParameters;
|
|
415
416
|
/**
|
|
@@ -560,6 +561,7 @@ declare function get_fuzz_range(interval: number, elapsed_days: number, maximum_
|
|
|
560
561
|
max_ivl: number;
|
|
561
562
|
};
|
|
562
563
|
declare function clamp(value: number, min: number, max: number): number;
|
|
564
|
+
declare function roundTo(num: number, decimals: number): number;
|
|
563
565
|
declare function dateDiffInDays(last: Date, cur: Date): number;
|
|
564
566
|
|
|
565
567
|
declare const ConvertStepUnitToMinutes: (step: StepUnit) => number;
|
|
@@ -587,5 +589,5 @@ declare function DefaultInitSeedStrategy(this: AbstractScheduler): string;
|
|
|
587
589
|
*/
|
|
588
590
|
declare function GenSeedStrategyWithCardId(card_id_field: string | number): TSeedStrategy;
|
|
589
591
|
|
|
590
|
-
export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, show_diff_message };
|
|
592
|
+
export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, roundTo, show_diff_message };
|
|
591
593
|
export type { Card, CardInput, DateInput, FSRSHistory, FSRSParameters, FSRSReview, FSRSState, Grade, GradeType, IFSRS, IPreview, IReschedule, IScheduler, RatingType, RecordLog, RecordLogItem, RescheduleOptions, ReviewLog, ReviewLogInput, StateType, StepUnit, Steps, TLearningStepsStrategy, TSchedulerStrategy, TSeedStrategy, TStrategyHandler, TimeUnit, double, int, unit };
|
package/dist/index.mjs
CHANGED
|
@@ -52,6 +52,9 @@ class TypeConvert {
|
|
|
52
52
|
throw new Error(`Invalid state:[${value}]`);
|
|
53
53
|
}
|
|
54
54
|
static time(value) {
|
|
55
|
+
if (value instanceof Date) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
55
58
|
const date = new Date(value);
|
|
56
59
|
if (typeof value === "object" && value !== null && !Number.isNaN(Date.parse(value) || +date)) {
|
|
57
60
|
return date;
|
|
@@ -78,15 +81,19 @@ class TypeConvert {
|
|
|
78
81
|
}
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
/* istanbul ignore next -- @preserve */
|
|
81
85
|
Date.prototype.scheduler = function(t, isDay) {
|
|
82
86
|
return date_scheduler(this, t, isDay);
|
|
83
87
|
};
|
|
88
|
+
/* istanbul ignore next -- @preserve */
|
|
84
89
|
Date.prototype.diff = function(pre, unit) {
|
|
85
90
|
return date_diff(this, pre, unit);
|
|
86
91
|
};
|
|
92
|
+
/* istanbul ignore next -- @preserve */
|
|
87
93
|
Date.prototype.format = function() {
|
|
88
94
|
return formatDate(this);
|
|
89
95
|
};
|
|
96
|
+
/* istanbul ignore next -- @preserve */
|
|
90
97
|
Date.prototype.dueFormat = function(last_review, unit, timeUnit) {
|
|
91
98
|
return show_diff_message(this, last_review, unit, timeUnit);
|
|
92
99
|
};
|
|
@@ -146,12 +153,15 @@ function show_diff_message(due, last_review, unit, timeUnit = TIMEUNITFORMAT) {
|
|
|
146
153
|
}
|
|
147
154
|
return `${Math.floor(diff)}${unit ? timeUnit[i] : ""}`;
|
|
148
155
|
}
|
|
156
|
+
/* istanbul ignore next -- @preserve */
|
|
149
157
|
function fixDate(value) {
|
|
150
158
|
return TypeConvert.time(value);
|
|
151
159
|
}
|
|
160
|
+
/* istanbul ignore next -- @preserve */
|
|
152
161
|
function fixState(value) {
|
|
153
162
|
return TypeConvert.state(value);
|
|
154
163
|
}
|
|
164
|
+
/* istanbul ignore next -- @preserve */
|
|
155
165
|
function fixRating(value) {
|
|
156
166
|
return TypeConvert.rating(value);
|
|
157
167
|
}
|
|
@@ -195,6 +205,10 @@ function get_fuzz_range(interval, elapsed_days, maximum_interval) {
|
|
|
195
205
|
function clamp(value, min, max) {
|
|
196
206
|
return Math.min(Math.max(value, min), max);
|
|
197
207
|
}
|
|
208
|
+
function roundTo(num, decimals) {
|
|
209
|
+
const factor = 10 ** decimals;
|
|
210
|
+
return Math.round(num * factor) / factor;
|
|
211
|
+
}
|
|
198
212
|
function dateDiffInDays(last, cur) {
|
|
199
213
|
const utc1 = Date.UTC(
|
|
200
214
|
last.getUTCFullYear(),
|
|
@@ -467,7 +481,7 @@ function alea(seed) {
|
|
|
467
481
|
return prng;
|
|
468
482
|
}
|
|
469
483
|
|
|
470
|
-
const version="5.
|
|
484
|
+
const version="5.3.0";
|
|
471
485
|
|
|
472
486
|
const default_request_retention = 0.9;
|
|
473
487
|
const default_maximum_interval = 36500;
|
|
@@ -641,11 +655,11 @@ function createEmptyCard(now, afterHandler) {
|
|
|
641
655
|
const computeDecayFactor = (decayOrParams) => {
|
|
642
656
|
const decay = typeof decayOrParams === "number" ? -decayOrParams : -decayOrParams[20];
|
|
643
657
|
const factor = Math.exp(Math.pow(decay, -1) * Math.log(0.9)) - 1;
|
|
644
|
-
return { decay, factor:
|
|
658
|
+
return { decay, factor: roundTo(factor, 8) };
|
|
645
659
|
};
|
|
646
660
|
function forgetting_curve(decayOrParams, elapsed_days, stability) {
|
|
647
661
|
const { decay, factor } = computeDecayFactor(decayOrParams);
|
|
648
|
-
return
|
|
662
|
+
return roundTo(Math.pow(1 + factor * elapsed_days / stability, decay), 8);
|
|
649
663
|
}
|
|
650
664
|
class FSRSAlgorithm {
|
|
651
665
|
param;
|
|
@@ -679,7 +693,7 @@ class FSRSAlgorithm {
|
|
|
679
693
|
throw new Error("Requested retention rate should be in the range (0,1]");
|
|
680
694
|
}
|
|
681
695
|
const { decay, factor } = computeDecayFactor(this.param.w);
|
|
682
|
-
return
|
|
696
|
+
return roundTo((Math.pow(request_retention, 1 / decay) - 1) / factor, 8);
|
|
683
697
|
}
|
|
684
698
|
/**
|
|
685
699
|
* Get the parameters of the algorithm.
|
|
@@ -746,8 +760,9 @@ class FSRSAlgorithm {
|
|
|
746
760
|
* @return {number} Difficulty $$D \in [1,10]$$
|
|
747
761
|
*/
|
|
748
762
|
init_difficulty(g) {
|
|
749
|
-
const
|
|
750
|
-
|
|
763
|
+
const w = this.param.w;
|
|
764
|
+
const d = w[4] - Math.exp((g - 1) * w[5]) + 1;
|
|
765
|
+
return roundTo(d, 8);
|
|
751
766
|
}
|
|
752
767
|
/**
|
|
753
768
|
* If fuzzing is disabled or ivl is less than 2.5, it returns the original interval.
|
|
@@ -782,7 +797,7 @@ class FSRSAlgorithm {
|
|
|
782
797
|
* @see https://github.com/open-spaced-repetition/fsrs4anki/issues/697
|
|
783
798
|
*/
|
|
784
799
|
linear_damping(delta_d, old_d) {
|
|
785
|
-
return
|
|
800
|
+
return roundTo(delta_d * (10 - old_d) / 9, 8);
|
|
786
801
|
}
|
|
787
802
|
/**
|
|
788
803
|
* The formula used is :
|
|
@@ -810,9 +825,8 @@ class FSRSAlgorithm {
|
|
|
810
825
|
* @return {number} difficulty
|
|
811
826
|
*/
|
|
812
827
|
mean_reversion(init, current) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
);
|
|
828
|
+
const w = this.param.w;
|
|
829
|
+
return roundTo(w[7] * init + (1 - w[7]) * current, 8);
|
|
816
830
|
}
|
|
817
831
|
/**
|
|
818
832
|
* The formula used is :
|
|
@@ -824,13 +838,17 @@ class FSRSAlgorithm {
|
|
|
824
838
|
* @return {number} S^\prime_r new stability after recall
|
|
825
839
|
*/
|
|
826
840
|
next_recall_stability(d, s, r, g) {
|
|
827
|
-
const
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
841
|
+
const w = this.param.w;
|
|
842
|
+
const hard_penalty = Rating.Hard === g ? w[15] : 1;
|
|
843
|
+
const easy_bound = Rating.Easy === g ? w[16] : 1;
|
|
844
|
+
return roundTo(
|
|
845
|
+
clamp(
|
|
846
|
+
s * (1 + Math.exp(w[8]) * (11 - d) * Math.pow(s, -w[9]) * (Math.exp((1 - r) * w[10]) - 1) * hard_penalty * easy_bound),
|
|
847
|
+
S_MIN,
|
|
848
|
+
36500
|
|
849
|
+
),
|
|
850
|
+
8
|
|
851
|
+
);
|
|
834
852
|
}
|
|
835
853
|
/**
|
|
836
854
|
* The formula used is :
|
|
@@ -843,11 +861,15 @@ class FSRSAlgorithm {
|
|
|
843
861
|
* @return {number} S^\prime_f new stability after forgetting
|
|
844
862
|
*/
|
|
845
863
|
next_forget_stability(d, s, r) {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
864
|
+
const w = this.param.w;
|
|
865
|
+
return roundTo(
|
|
866
|
+
clamp(
|
|
867
|
+
w[11] * Math.pow(d, -w[12]) * (Math.pow(s + 1, w[13]) - 1) * Math.exp((1 - r) * w[14]),
|
|
868
|
+
S_MIN,
|
|
869
|
+
36500
|
|
870
|
+
),
|
|
871
|
+
8
|
|
872
|
+
);
|
|
851
873
|
}
|
|
852
874
|
/**
|
|
853
875
|
* The formula used is :
|
|
@@ -856,9 +878,10 @@ class FSRSAlgorithm {
|
|
|
856
878
|
* @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])
|
|
857
879
|
*/
|
|
858
880
|
next_short_term_stability(s, g) {
|
|
859
|
-
const
|
|
860
|
-
const
|
|
861
|
-
|
|
881
|
+
const w = this.param.w;
|
|
882
|
+
const sinc = Math.pow(s, -w[19]) * Math.exp(w[17] * (g - 3 + w[18]));
|
|
883
|
+
const maskedSinc = g >= Rating.Hard ? Math.max(sinc, 1) : sinc;
|
|
884
|
+
return roundTo(clamp(s * maskedSinc, S_MIN, 36500), 8);
|
|
862
885
|
}
|
|
863
886
|
/**
|
|
864
887
|
* The formula used is :
|
|
@@ -874,9 +897,10 @@ class FSRSAlgorithm {
|
|
|
874
897
|
* @param memory_state - The current state of memory, which can be null.
|
|
875
898
|
* @param t - The time elapsed since the last review.
|
|
876
899
|
* @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])
|
|
900
|
+
* @param r - Optional retrievability value. If not provided, it will be calculated.
|
|
877
901
|
* @returns The next state of memory with updated difficulty and stability.
|
|
878
902
|
*/
|
|
879
|
-
next_state(memory_state, t, g) {
|
|
903
|
+
next_state(memory_state, t, g, r) {
|
|
880
904
|
const { difficulty: d, stability: s } = memory_state ?? {
|
|
881
905
|
difficulty: 0,
|
|
882
906
|
stability: 0
|
|
@@ -904,22 +928,22 @@ class FSRSAlgorithm {
|
|
|
904
928
|
`Invalid memory state { difficulty: ${d}, stability: ${s} }`
|
|
905
929
|
);
|
|
906
930
|
}
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
if (g === 1) {
|
|
931
|
+
const w = this.param.w;
|
|
932
|
+
r = typeof r === "number" ? r : this.forgetting_curve(t, s);
|
|
933
|
+
let new_s;
|
|
934
|
+
if (t === 0 && this.param.enable_short_term) {
|
|
935
|
+
new_s = this.next_short_term_stability(s, g);
|
|
936
|
+
} else if (g === 1) {
|
|
937
|
+
const s_after_fail = this.next_forget_stability(d, s, r);
|
|
913
938
|
let [w_17, w_18] = [0, 0];
|
|
914
939
|
if (this.param.enable_short_term) {
|
|
915
|
-
w_17 =
|
|
916
|
-
w_18 =
|
|
940
|
+
w_17 = w[17];
|
|
941
|
+
w_18 = w[18];
|
|
917
942
|
}
|
|
918
943
|
const next_s_min = s / Math.exp(w_17 * w_18);
|
|
919
|
-
new_s = clamp(
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
new_s = s_after_short_term;
|
|
944
|
+
new_s = clamp(roundTo(next_s_min, 8), S_MIN, s_after_fail);
|
|
945
|
+
} else {
|
|
946
|
+
new_s = this.next_recall_stability(d, s, r, g);
|
|
923
947
|
}
|
|
924
948
|
const new_d = this.next_difficulty(d, g);
|
|
925
949
|
return { difficulty: new_d, stability: new_s };
|
|
@@ -1004,9 +1028,7 @@ class BasicScheduler extends AbstractScheduler {
|
|
|
1004
1028
|
if (exist) {
|
|
1005
1029
|
return exist;
|
|
1006
1030
|
}
|
|
1007
|
-
const next =
|
|
1008
|
-
next.difficulty = clamp(this.algorithm.init_difficulty(grade), 1, 10);
|
|
1009
|
-
next.stability = this.algorithm.init_stability(grade);
|
|
1031
|
+
const next = this.next_ds(this.elapsed_days, grade);
|
|
1010
1032
|
this.applyLearningSteps(next, grade, State.Learning);
|
|
1011
1033
|
const item = {
|
|
1012
1034
|
card: next,
|
|
@@ -1020,14 +1042,11 @@ class BasicScheduler extends AbstractScheduler {
|
|
|
1020
1042
|
if (exist) {
|
|
1021
1043
|
return exist;
|
|
1022
1044
|
}
|
|
1023
|
-
const
|
|
1024
|
-
const next = TypeConvert.card(this.current);
|
|
1025
|
-
next.difficulty = this.algorithm.next_difficulty(difficulty, grade);
|
|
1026
|
-
next.stability = this.algorithm.next_short_term_stability(stability, grade);
|
|
1045
|
+
const next = this.next_ds(this.elapsed_days, grade);
|
|
1027
1046
|
this.applyLearningSteps(
|
|
1028
1047
|
next,
|
|
1029
1048
|
grade,
|
|
1030
|
-
state
|
|
1049
|
+
this.last.state
|
|
1031
1050
|
/** Learning or Relearning */
|
|
1032
1051
|
);
|
|
1033
1052
|
const item = {
|
|
@@ -1043,21 +1062,14 @@ class BasicScheduler extends AbstractScheduler {
|
|
|
1043
1062
|
return exist;
|
|
1044
1063
|
}
|
|
1045
1064
|
const interval = this.elapsed_days;
|
|
1046
|
-
const
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1050
|
-
const next_good = TypeConvert.card(this.current);
|
|
1051
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1052
|
-
this.next_ds(
|
|
1053
|
-
next_again,
|
|
1054
|
-
next_hard,
|
|
1055
|
-
next_good,
|
|
1056
|
-
next_easy,
|
|
1057
|
-
difficulty,
|
|
1058
|
-
stability,
|
|
1059
|
-
retrievability
|
|
1065
|
+
const retrievability = this.algorithm.forgetting_curve(
|
|
1066
|
+
interval,
|
|
1067
|
+
this.current.stability
|
|
1060
1068
|
);
|
|
1069
|
+
const next_again = this.next_ds(interval, Rating.Again, retrievability);
|
|
1070
|
+
const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
|
|
1071
|
+
const next_good = this.next_ds(interval, Rating.Good, retrievability);
|
|
1072
|
+
const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
|
|
1061
1073
|
this.next_interval(next_hard, next_good, next_easy, interval);
|
|
1062
1074
|
this.next_state(next_hard, next_good, next_easy);
|
|
1063
1075
|
this.applyLearningSteps(next_again, Rating.Again, State.Relearning);
|
|
@@ -1087,50 +1099,20 @@ class BasicScheduler extends AbstractScheduler {
|
|
|
1087
1099
|
/**
|
|
1088
1100
|
* Review next_ds
|
|
1089
1101
|
*/
|
|
1090
|
-
next_ds(
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
difficulty,
|
|
1100
|
-
stability,
|
|
1101
|
-
retrievability
|
|
1102
|
-
);
|
|
1103
|
-
next_again.stability = clamp(+nextSMin.toFixed(8), S_MIN, s_after_fail);
|
|
1104
|
-
next_hard.difficulty = this.algorithm.next_difficulty(
|
|
1105
|
-
difficulty,
|
|
1106
|
-
Rating.Hard
|
|
1107
|
-
);
|
|
1108
|
-
next_hard.stability = this.algorithm.next_recall_stability(
|
|
1109
|
-
difficulty,
|
|
1110
|
-
stability,
|
|
1111
|
-
retrievability,
|
|
1112
|
-
Rating.Hard
|
|
1113
|
-
);
|
|
1114
|
-
next_good.difficulty = this.algorithm.next_difficulty(
|
|
1115
|
-
difficulty,
|
|
1116
|
-
Rating.Good
|
|
1117
|
-
);
|
|
1118
|
-
next_good.stability = this.algorithm.next_recall_stability(
|
|
1119
|
-
difficulty,
|
|
1120
|
-
stability,
|
|
1121
|
-
retrievability,
|
|
1122
|
-
Rating.Good
|
|
1123
|
-
);
|
|
1124
|
-
next_easy.difficulty = this.algorithm.next_difficulty(
|
|
1125
|
-
difficulty,
|
|
1126
|
-
Rating.Easy
|
|
1127
|
-
);
|
|
1128
|
-
next_easy.stability = this.algorithm.next_recall_stability(
|
|
1129
|
-
difficulty,
|
|
1130
|
-
stability,
|
|
1131
|
-
retrievability,
|
|
1132
|
-
Rating.Easy
|
|
1102
|
+
next_ds(t, g, r) {
|
|
1103
|
+
const next_state = this.algorithm.next_state(
|
|
1104
|
+
{
|
|
1105
|
+
difficulty: this.current.difficulty,
|
|
1106
|
+
stability: this.current.stability
|
|
1107
|
+
},
|
|
1108
|
+
t,
|
|
1109
|
+
g,
|
|
1110
|
+
r
|
|
1133
1111
|
);
|
|
1112
|
+
const card = TypeConvert.card(this.current);
|
|
1113
|
+
card.difficulty = next_state.difficulty;
|
|
1114
|
+
card.stability = next_state.stability;
|
|
1115
|
+
return card;
|
|
1134
1116
|
}
|
|
1135
1117
|
/**
|
|
1136
1118
|
* Review next_interval
|
|
@@ -1173,12 +1155,11 @@ class LongTermScheduler extends AbstractScheduler {
|
|
|
1173
1155
|
}
|
|
1174
1156
|
this.current.scheduled_days = 0;
|
|
1175
1157
|
this.current.elapsed_days = 0;
|
|
1176
|
-
const next_again = TypeConvert.card(this.current);
|
|
1177
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1178
|
-
const next_good = TypeConvert.card(this.current);
|
|
1179
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1180
|
-
this.init_ds(next_again, next_hard, next_good, next_easy);
|
|
1181
1158
|
const first_interval = 0;
|
|
1159
|
+
const next_again = this.next_ds(first_interval, Rating.Again);
|
|
1160
|
+
const next_hard = this.next_ds(first_interval, Rating.Hard);
|
|
1161
|
+
const next_good = this.next_ds(first_interval, Rating.Good);
|
|
1162
|
+
const next_easy = this.next_ds(first_interval, Rating.Easy);
|
|
1182
1163
|
this.next_interval(
|
|
1183
1164
|
next_again,
|
|
1184
1165
|
next_hard,
|
|
@@ -1190,31 +1171,20 @@ class LongTermScheduler extends AbstractScheduler {
|
|
|
1190
1171
|
this.update_next(next_again, next_hard, next_good, next_easy);
|
|
1191
1172
|
return this.next.get(grade);
|
|
1192
1173
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
1,
|
|
1203
|
-
10
|
|
1204
|
-
);
|
|
1205
|
-
next_hard.stability = this.algorithm.init_stability(Rating.Hard);
|
|
1206
|
-
next_good.difficulty = clamp(
|
|
1207
|
-
this.algorithm.init_difficulty(Rating.Good),
|
|
1208
|
-
1,
|
|
1209
|
-
10
|
|
1210
|
-
);
|
|
1211
|
-
next_good.stability = this.algorithm.init_stability(Rating.Good);
|
|
1212
|
-
next_easy.difficulty = clamp(
|
|
1213
|
-
this.algorithm.init_difficulty(Rating.Easy),
|
|
1214
|
-
1,
|
|
1215
|
-
10
|
|
1174
|
+
next_ds(t, g, r) {
|
|
1175
|
+
const next_state = this.algorithm.next_state(
|
|
1176
|
+
{
|
|
1177
|
+
difficulty: this.current.difficulty,
|
|
1178
|
+
stability: this.current.stability
|
|
1179
|
+
},
|
|
1180
|
+
t,
|
|
1181
|
+
g,
|
|
1182
|
+
r
|
|
1216
1183
|
);
|
|
1217
|
-
|
|
1184
|
+
const card = TypeConvert.card(this.current);
|
|
1185
|
+
card.difficulty = next_state.difficulty;
|
|
1186
|
+
card.stability = next_state.stability;
|
|
1187
|
+
return card;
|
|
1218
1188
|
}
|
|
1219
1189
|
/**
|
|
1220
1190
|
* @see https://github.com/open-spaced-repetition/ts-fsrs/issues/98#issuecomment-2241923194
|
|
@@ -1228,72 +1198,20 @@ class LongTermScheduler extends AbstractScheduler {
|
|
|
1228
1198
|
return exist;
|
|
1229
1199
|
}
|
|
1230
1200
|
const interval = this.elapsed_days;
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1235
|
-
const next_good = TypeConvert.card(this.current);
|
|
1236
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1237
|
-
this.next_ds(
|
|
1238
|
-
next_again,
|
|
1239
|
-
next_hard,
|
|
1240
|
-
next_good,
|
|
1241
|
-
next_easy,
|
|
1242
|
-
difficulty,
|
|
1243
|
-
stability,
|
|
1244
|
-
retrievability
|
|
1201
|
+
const retrievability = this.algorithm.forgetting_curve(
|
|
1202
|
+
interval,
|
|
1203
|
+
this.current.stability
|
|
1245
1204
|
);
|
|
1205
|
+
const next_again = this.next_ds(interval, Rating.Again, retrievability);
|
|
1206
|
+
const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
|
|
1207
|
+
const next_good = this.next_ds(interval, Rating.Good, retrievability);
|
|
1208
|
+
const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
|
|
1246
1209
|
this.next_interval(next_again, next_hard, next_good, next_easy, interval);
|
|
1247
1210
|
this.next_state(next_again, next_hard, next_good, next_easy);
|
|
1248
1211
|
next_again.lapses += 1;
|
|
1249
1212
|
this.update_next(next_again, next_hard, next_good, next_easy);
|
|
1250
1213
|
return this.next.get(grade);
|
|
1251
1214
|
}
|
|
1252
|
-
/**
|
|
1253
|
-
* Review next_ds
|
|
1254
|
-
*/
|
|
1255
|
-
next_ds(next_again, next_hard, next_good, next_easy, difficulty, stability, retrievability) {
|
|
1256
|
-
next_again.difficulty = this.algorithm.next_difficulty(
|
|
1257
|
-
difficulty,
|
|
1258
|
-
Rating.Again
|
|
1259
|
-
);
|
|
1260
|
-
const s_after_fail = this.algorithm.next_forget_stability(
|
|
1261
|
-
difficulty,
|
|
1262
|
-
stability,
|
|
1263
|
-
retrievability
|
|
1264
|
-
);
|
|
1265
|
-
next_again.stability = clamp(stability, S_MIN, s_after_fail);
|
|
1266
|
-
next_hard.difficulty = this.algorithm.next_difficulty(
|
|
1267
|
-
difficulty,
|
|
1268
|
-
Rating.Hard
|
|
1269
|
-
);
|
|
1270
|
-
next_hard.stability = this.algorithm.next_recall_stability(
|
|
1271
|
-
difficulty,
|
|
1272
|
-
stability,
|
|
1273
|
-
retrievability,
|
|
1274
|
-
Rating.Hard
|
|
1275
|
-
);
|
|
1276
|
-
next_good.difficulty = this.algorithm.next_difficulty(
|
|
1277
|
-
difficulty,
|
|
1278
|
-
Rating.Good
|
|
1279
|
-
);
|
|
1280
|
-
next_good.stability = this.algorithm.next_recall_stability(
|
|
1281
|
-
difficulty,
|
|
1282
|
-
stability,
|
|
1283
|
-
retrievability,
|
|
1284
|
-
Rating.Good
|
|
1285
|
-
);
|
|
1286
|
-
next_easy.difficulty = this.algorithm.next_difficulty(
|
|
1287
|
-
difficulty,
|
|
1288
|
-
Rating.Easy
|
|
1289
|
-
);
|
|
1290
|
-
next_easy.stability = this.algorithm.next_recall_stability(
|
|
1291
|
-
difficulty,
|
|
1292
|
-
stability,
|
|
1293
|
-
retrievability,
|
|
1294
|
-
Rating.Easy
|
|
1295
|
-
);
|
|
1296
|
-
}
|
|
1297
1215
|
/**
|
|
1298
1216
|
* Review/New next_interval
|
|
1299
1217
|
*/
|
|
@@ -1937,5 +1855,5 @@ const fsrs = (params) => {
|
|
|
1937
1855
|
return new FSRS(params || {});
|
|
1938
1856
|
};
|
|
1939
1857
|
|
|
1940
|
-
export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, show_diff_message };
|
|
1858
|
+
export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, roundTo, show_diff_message };
|
|
1941
1859
|
//# sourceMappingURL=index.mjs.map
|