ts-fsrs 5.2.0 → 5.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/fsrs/models.ts","../src/fsrs/convert.ts","../src/fsrs/help.ts","../src/fsrs/constant.ts","../src/fsrs/default.ts","../src/fsrs/alea.ts","../src/fsrs/algorithm.ts","../src/fsrs/strategies/seed.ts","../src/fsrs/strategies/learning_steps.ts","../src/fsrs/strategies/types.ts","../src/fsrs/abstract_scheduler.ts","../src/fsrs/impl/basic_scheduler.ts","../src/fsrs/impl/long_term_scheduler.ts","../src/fsrs/reschedule.ts","../src/fsrs/fsrs.ts"],"sourcesContent":["export type StateType = 'New' | 'Learning' | 'Review' | 'Relearning'\n\nexport enum State {\n New = 0,\n Learning = 1,\n Review = 2,\n Relearning = 3,\n}\n\nexport type RatingType = 'Manual' | 'Again' | 'Hard' | 'Good' | 'Easy'\n\nexport enum Rating {\n Manual = 0,\n Again = 1,\n Hard = 2,\n Good = 3,\n Easy = 4,\n}\n\nexport type GradeType = Exclude<RatingType, 'Manual'>\nexport type Grade = Exclude<Rating, Rating.Manual>\n\nexport interface ReviewLog {\n rating: Rating // Rating of the review (Again, Hard, Good, Easy)\n state: State // State of the review (New, Learning, Review, Relearning)\n due: Date // Date of the last scheduling\n stability: number // Memory stability during the review\n difficulty: number // Difficulty of the card during the review\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n elapsed_days: number // Number of days elapsed since the last review\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n last_elapsed_days: number // Number of days between the last two reviews\n scheduled_days: number // Number of days until the next review\n learning_steps: number // Keeps track of the current step during the (re)learning stages\n review: Date // Date of the review\n}\n\nexport type RecordLogItem = {\n card: Card\n log: ReviewLog\n}\nexport type RecordLog = {\n [key in Grade]: RecordLogItem\n}\n\nexport interface Card {\n due: Date // Due date\n stability: number // Stability\n difficulty: number // Difficulty level\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n elapsed_days: number // Number of days elapsed\n scheduled_days: number // Number of days scheduled\n learning_steps: number // Keeps track of the current step during the (re)learning stages\n reps: number // Repetition count\n lapses: number // Number of lapses or mistakes\n state: State // Card's state (New, Learning, Review, Relearning)\n last_review?: Date // Date of the last review (optional)\n}\n\nexport interface CardInput extends Omit<Card, 'state' | 'due' | 'last_review'> {\n state: StateType | State // Card's state (New, Learning, Review, Relearning)\n due: DateInput // Due date\n last_review?: DateInput | null // Date of the last review (optional)\n}\n\nexport type DateInput = Date | number | string\nexport type TimeUnit = 'm' | 'h' | 'd'\nexport type StepUnit = `${number}${TimeUnit}`\n/**\n * (re)Learning steps:\n * [1m, 10m]\n * step1:again=1m hard=6m good=10m\n * step2(good): again=1m hard=10m\n *\n * [5m]\n * step1:again=5m hard=8m\n * step2(good): again=5m\n * step2(hard): again=5m hard=7.5m\n *\n * []\n * step: Managed by FSRS\n *\n */\nexport type Steps = StepUnit[] | readonly StepUnit[]\n\nexport interface ReviewLogInput\n extends Omit<ReviewLog, 'rating' | 'state' | 'due' | 'review'> {\n rating: RatingType | Rating // Rating of the review (Again, Hard, Good, Easy)\n state: StateType | State // Card's state (New, Learning, Review, Relearning)\n due: DateInput // Due date\n review: DateInput // Date of the last review\n}\n\nexport interface FSRSParameters {\n request_retention: number\n maximum_interval: number\n w: number[] | readonly number[]\n enable_fuzz: boolean\n /**\n * When enable_short_term = false, the (re)learning steps are not applied.\n */\n enable_short_term: boolean\n learning_steps: Steps\n relearning_steps: Steps\n}\n\nexport interface FSRSReview {\n /**\n * 0-4: Manual, Again, Hard, Good, Easy\n * = revlog.rating\n */\n rating: Rating\n /**\n * The number of days that passed\n * = revlog.elapsed_days\n * = round(revlog[-1].review - revlog[-2].review)\n */\n delta_t: number\n}\n\nexport type FSRSHistory = Partial<\n Omit<ReviewLog, 'rating' | 'review' | 'elapsed_days'>\n> &\n (\n | {\n rating: Grade\n review: DateInput | Date\n }\n | {\n rating: Rating.Manual\n due: DateInput | Date\n state: State\n review: DateInput | Date\n }\n )\n\nexport interface FSRSState {\n stability: number\n difficulty: number\n}\n","import {\n Card,\n CardInput,\n Rating,\n ReviewLog,\n ReviewLogInput,\n State,\n} from './models'\n\nexport class TypeConvert {\n static card<T extends Card | CardInput>(card: T): Card {\n return {\n ...card,\n state: TypeConvert.state(card.state),\n due: TypeConvert.time(card.due),\n last_review: card.last_review\n ? TypeConvert.time(card.last_review)\n : undefined,\n } as Card\n }\n static rating(value: unknown): Rating {\n if (typeof value === 'string') {\n const firstLetter = value.charAt(0).toUpperCase()\n const restOfString = value.slice(1).toLowerCase()\n const ret = Rating[`${firstLetter}${restOfString}` as keyof typeof Rating]\n if (ret === undefined) {\n throw new Error(`Invalid rating:[${value}]`)\n }\n return ret\n } else if (typeof value === 'number') {\n return value as Rating\n }\n throw new Error(`Invalid rating:[${value}]`)\n }\n static state(value: unknown): State {\n if (typeof value === 'string') {\n const firstLetter = value.charAt(0).toUpperCase()\n const restOfString = value.slice(1).toLowerCase()\n const ret = State[`${firstLetter}${restOfString}` as keyof typeof State]\n if (ret === undefined) {\n throw new Error(`Invalid state:[${value}]`)\n }\n return ret\n } else if (typeof value === 'number') {\n return value as State\n }\n throw new Error(`Invalid state:[${value}]`)\n }\n static time(value: unknown): Date {\n if (typeof value === 'object' && value instanceof Date) {\n return value\n } else if (typeof value === 'string') {\n const timestamp = Date.parse(value)\n if (!isNaN(timestamp)) {\n return new Date(timestamp)\n } else {\n throw new Error(`Invalid date:[${value}]`)\n }\n } else if (typeof value === 'number') {\n return new Date(value)\n }\n throw new Error(`Invalid date:[${value}]`)\n }\n static review_log(log: ReviewLogInput | ReviewLog): ReviewLog {\n return {\n ...log,\n due: TypeConvert.time(log.due),\n rating: TypeConvert.rating(log.rating),\n state: TypeConvert.state(log.state),\n review: TypeConvert.time(log.review),\n } satisfies ReviewLog\n }\n}\n","import type { int, unit } from './types'\nimport type { DateInput, Grade } from './models'\nimport { Rating, State } from './models'\nimport { TypeConvert } from './convert'\n\ndeclare global {\n export interface Date {\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n scheduler(t: int, isDay?: boolean): Date\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n diff(pre: Date, unit: unit): int\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n format(): string\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n dueFormat(last_review: Date, unit?: boolean, timeUnit?: string[]): string\n }\n}\n\nDate.prototype.scheduler = function (t: int, isDay?: boolean): Date {\n return date_scheduler(this, t, isDay)\n}\n\n/**\n * 当前时间与之前的时间差值\n * @param pre 比当前时间还要之前\n * @param unit 单位: days | minutes\n */\nDate.prototype.diff = function (pre: Date, unit: unit): int {\n return date_diff(this, pre, unit) as int\n}\n\nDate.prototype.format = function (): string {\n return formatDate(this)\n}\n\nDate.prototype.dueFormat = function (\n last_review: Date,\n unit?: boolean,\n timeUnit?: string[]\n) {\n return show_diff_message(this, last_review, unit, timeUnit)\n}\n\n/**\n * 计算日期和时间的偏移,并返回一个新的日期对象。\n * @param now 当前日期和时间\n * @param t 时间偏移量,当 isDay 为 true 时表示天数,为 false 时表示分钟\n * @param isDay (可选)是否按天数单位进行偏移,默认为 false,表示按分钟单位计算偏移\n * @returns 偏移后的日期和时间对象\n */\nexport function date_scheduler(\n now: DateInput,\n t: number,\n isDay?: boolean\n): Date {\n return new Date(\n isDay\n ? TypeConvert.time(now).getTime() + t * 24 * 60 * 60 * 1000\n : TypeConvert.time(now).getTime() + t * 60 * 1000\n )\n}\n\nexport function date_diff(now: DateInput, pre: DateInput, unit: unit): number {\n if (!now || !pre) {\n throw new Error('Invalid date')\n }\n const diff = TypeConvert.time(now).getTime() - TypeConvert.time(pre).getTime()\n let r = 0\n switch (unit) {\n case 'days':\n r = Math.floor(diff / (24 * 60 * 60 * 1000))\n break\n case 'minutes':\n r = Math.floor(diff / (60 * 1000))\n break\n }\n return r\n}\n\nexport function formatDate(dateInput: DateInput): string {\n const date = TypeConvert.time(dateInput)\n const year: number = date.getFullYear()\n const month: number = date.getMonth() + 1\n const day: number = date.getDate()\n const hours: number = date.getHours()\n const minutes: number = date.getMinutes()\n const seconds: number = date.getSeconds()\n\n return `${year}-${padZero(month)}-${padZero(day)} ${padZero(hours)}:${padZero(\n minutes\n )}:${padZero(seconds)}`\n}\n\nfunction padZero(num: number): string {\n return num < 10 ? `0${num}` : `${num}`\n}\n\nconst TIMEUNIT = [60, 60, 24, 31, 12]\nconst TIMEUNITFORMAT = ['second', 'min', 'hour', 'day', 'month', 'year']\n\nexport function show_diff_message(\n due: DateInput,\n last_review: DateInput,\n unit?: boolean,\n timeUnit: string[] = TIMEUNITFORMAT\n): string {\n due = TypeConvert.time(due)\n last_review = TypeConvert.time(last_review)\n if (timeUnit.length !== TIMEUNITFORMAT.length) {\n timeUnit = TIMEUNITFORMAT\n }\n let diff = due.getTime() - last_review.getTime()\n let i\n diff /= 1000\n for (i = 0; i < TIMEUNIT.length; i++) {\n if (diff < TIMEUNIT[i]) {\n break\n } else {\n diff /= TIMEUNIT[i]\n }\n }\n return `${Math.floor(diff)}${unit ? timeUnit[i] : ''}`\n}\n\n/**\n *\n * @deprecated Use TypeConvert.time instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixDate(value: unknown) {\n return TypeConvert.time(value)\n}\n\n/**\n * @deprecated Use TypeConvert.state instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixState(value: unknown): State {\n return TypeConvert.state(value)\n}\n\n/**\n * @deprecated Use TypeConvert.rating instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixRating(value: unknown): Rating {\n return TypeConvert.rating(value)\n}\n\nexport const Grades: Readonly<Grade[]> = Object.freeze([\n Rating.Again,\n Rating.Hard,\n Rating.Good,\n Rating.Easy,\n])\n\nconst FUZZ_RANGES = [\n {\n start: 2.5,\n end: 7.0,\n factor: 0.15,\n },\n {\n start: 7.0,\n end: 20.0,\n factor: 0.1,\n },\n {\n start: 20.0,\n end: Infinity,\n factor: 0.05,\n },\n] as const\n\nexport function get_fuzz_range(\n interval: number,\n elapsed_days: number,\n maximum_interval: number\n) {\n let delta = 1.0\n for (const range of FUZZ_RANGES) {\n delta +=\n range.factor * Math.max(Math.min(interval, range.end) - range.start, 0.0)\n }\n interval = Math.min(interval, maximum_interval)\n let min_ivl = Math.max(2, Math.round(interval - delta))\n const max_ivl = Math.min(Math.round(interval + delta), maximum_interval)\n if (interval > elapsed_days) {\n min_ivl = Math.max(min_ivl, elapsed_days + 1)\n }\n min_ivl = Math.min(min_ivl, max_ivl)\n return { min_ivl, max_ivl }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n\nexport function dateDiffInDays(last: Date, cur: Date) {\n // Discard the time and time-zone information.\n const utc1 = Date.UTC(\n last.getUTCFullYear(),\n last.getUTCMonth(),\n last.getUTCDate()\n )\n const utc2 = Date.UTC(\n cur.getUTCFullYear(),\n cur.getUTCMonth(),\n cur.getUTCDate()\n )\n\n return Math.floor((utc2 - utc1) / 86400000 /** 1000 * 60 * 60 * 24*/)\n}\n","import { version } from '../../package.json'\nimport type { StepUnit } from './models'\n\nexport const default_request_retention = 0.9\nexport const default_maximum_interval = 36500\nexport const default_enable_fuzz = false\nexport const default_enable_short_term = true\nexport const default_learning_steps: readonly StepUnit[] = Object.freeze([\n '1m',\n '10m',\n]) // New->Learning,Learning->Learning\n\nexport const default_relearning_steps: readonly StepUnit[] = Object.freeze([\n '10m',\n]) // Relearning->Relearning\n\nexport const FSRSVersion: string = `v${version} using FSRS-6.0`\n\nexport const S_MIN = 0.001\nexport const S_MAX = 36500.0\nexport const INIT_S_MAX = 100.0\nexport const FSRS5_DEFAULT_DECAY = 0.5\nexport const FSRS6_DEFAULT_DECAY = 0.1542\nexport const default_w = Object.freeze([\n 0.212,\n 1.2931,\n 2.3065,\n 8.2956,\n 6.4133,\n 0.8334,\n 3.0194,\n 0.001,\n 1.8722,\n 0.1666,\n 0.796,\n 1.4835,\n 0.0614,\n 0.2629,\n 1.6483,\n 0.6014,\n 1.8729,\n 0.5425,\n 0.0912,\n 0.0658,\n FSRS6_DEFAULT_DECAY,\n]) satisfies readonly number[]\n\nexport const W17_W18_Ceiling = 2.0\nexport const CLAMP_PARAMETERS = (w17_w18_ceiling: number) => [\n [S_MIN, INIT_S_MAX] /** initial stability (Again) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Hard) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Good) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Easy) */,\n [1.0, 10.0] /** initial difficulty (Good) */,\n [0.001, 4.0] /** initial difficulty (multiplier) */,\n [0.001, 4.0] /** difficulty (multiplier) */,\n [0.001, 0.75] /** difficulty (multiplier) */,\n [0.0, 4.5] /** stability (exponent) */,\n [0.0, 0.8] /** stability (negative power) */,\n [0.001, 3.5] /** stability (exponent) */,\n [0.001, 5.0] /** fail stability (multiplier) */,\n [0.001, 0.25] /** fail stability (negative power) */,\n [0.001, 0.9] /** fail stability (power) */,\n [0.0, 4.0] /** fail stability (exponent) */,\n [0.0, 1.0] /** stability (multiplier for Hard) */,\n [1.0, 6.0] /** stability (multiplier for Easy) */,\n [0.0, w17_w18_ceiling] /** short-term stability (exponent) */,\n [0.0, w17_w18_ceiling] /** short-term stability (exponent) */,\n [0.0, 0.8] /** short-term last-stability (exponent) */,\n [0.1, 0.8] /** decay */,\n]\n","import { Card, DateInput, FSRSParameters, State } from './models'\nimport { TypeConvert } from './convert'\nimport { clamp } from './help'\nimport {\n CLAMP_PARAMETERS,\n default_enable_fuzz,\n default_enable_short_term,\n default_learning_steps,\n default_maximum_interval,\n default_relearning_steps,\n default_request_retention,\n default_w,\n FSRS5_DEFAULT_DECAY,\n W17_W18_Ceiling,\n} from './constant'\n\nexport const clipParameters = (\n parameters: number[],\n numRelearningSteps: number\n) => {\n let w17_w18_ceiling = W17_W18_Ceiling\n if (Math.max(0, numRelearningSteps) > 1) {\n // PLS = w11 * D ^ -w12 * [(S + 1) ^ w13 - 1] * e ^ (w14 * (1 - R))\n // PLS * e ^ (num_relearning_steps * w17 * w18) should be <= S\n // Given D = 1, R = 0.7, S = 1, PLS is equal to w11 * (2 ^ w13 - 1) * e ^ (w14 * 0.3)\n // So num_relearning_steps * w17 * w18 + ln(w11) + ln(2 ^ w13 - 1) + w14 * 0.3 should be <= ln(1)\n // => num_relearning_steps * w17 * w18 <= - ln(w11) - ln(2 ^ w13 - 1) - w14 * 0.3\n // => w17 * w18 <= -[ln(w11) + ln(2 ^ w13 - 1) + w14 * 0.3] / num_relearning_steps\n const value =\n -(\n Math.log(parameters[11]) +\n Math.log(Math.pow(2.0, parameters[13]) - 1.0) +\n parameters[14] * 0.3\n ) / numRelearningSteps\n\n w17_w18_ceiling = clamp(+value.toFixed(8), 0.01, 2.0)\n }\n const clip = CLAMP_PARAMETERS(w17_w18_ceiling)\n return clip.map(([min, max], index) => clamp(parameters[index], min, max))\n}\n\n/**\n * @returns The input if the parameters are valid, throws if they are invalid\n * @example\n * try {\n * generatorParameters({\n * w: checkParameters([0.40255])\n * });\n * } catch (e: any) {\n * alert(e);\n * }\n */\nexport const checkParameters = (parameters: number[] | readonly number[]) => {\n const invalid = parameters.find((param) => !isFinite(param) && !isNaN(param))\n if (invalid !== undefined) {\n throw Error(`Non-finite or NaN value in parameters ${parameters}`)\n } else if (![17, 19, 21].includes(parameters.length)) {\n throw Error(\n `Invalid parameter length: ${parameters.length}. Must be 17, 19 or 21 for FSRSv4, 5 and 6 respectively.`\n )\n }\n return parameters\n}\n\nexport const migrateParameters = (\n parameters?: number[] | readonly number[]\n) => {\n if (parameters === undefined) {\n return [...default_w]\n }\n switch (parameters.length) {\n case 21:\n return [...parameters]\n case 19:\n console.debug('[FSRS-6]auto fill w from 19 to 21 length')\n return [...parameters, 0.0, FSRS5_DEFAULT_DECAY]\n case 17: {\n const w = [...parameters]\n w[4] = +(w[5] * 2.0 + w[4]).toFixed(8)\n w[5] = +(Math.log(w[5] * 3.0 + 1.0) / 3.0).toFixed(8)\n w[6] = +(w[6] + 0.5).toFixed(8)\n console.debug('[FSRS-6]auto fill w from 17 to 21 length')\n return w.concat([0.0, 0.0, 0.0, FSRS5_DEFAULT_DECAY])\n }\n default:\n // To throw use \"checkParameters\"\n // ref: https://github.com/open-spaced-repetition/ts-fsrs/pull/174#discussion_r2070436201\n console.warn('[FSRS]Invalid parameters length, using default parameters')\n return [...default_w]\n }\n}\n\nexport const generatorParameters = (\n props?: Partial<FSRSParameters>\n): FSRSParameters => {\n const learning_steps = Array.isArray(props?.learning_steps)\n ? props!.learning_steps\n : default_learning_steps\n const relearning_steps = Array.isArray(props?.relearning_steps)\n ? props!.relearning_steps\n : default_relearning_steps\n const w = clipParameters(migrateParameters(props?.w), relearning_steps.length)\n return {\n request_retention: props?.request_retention || default_request_retention,\n maximum_interval: props?.maximum_interval || default_maximum_interval,\n w: w,\n enable_fuzz: props?.enable_fuzz ?? default_enable_fuzz,\n enable_short_term: props?.enable_short_term ?? default_enable_short_term,\n learning_steps: learning_steps,\n relearning_steps: relearning_steps,\n } satisfies FSRSParameters\n}\n\n/**\n * Create an empty card\n * @param now Current time\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * ```\n * @example\n * ```typescript\n * interface CardUnChecked\n * extends Omit<Card, \"due\" | \"last_review\" | \"state\"> {\n * cid: string;\n * due: Date | number;\n * last_review: Date | null | number;\n * state: StateType;\n * }\n *\n * function cardAfterHandler(card: Card) {\n * return {\n * ...card,\n * cid: \"test001\",\n * state: State[card.state],\n * last_review: card.last_review ?? null,\n * } as CardUnChecked;\n * }\n *\n * const card: CardUnChecked = createEmptyCard(new Date(), cardAfterHandler);\n * ```\n */\nexport function createEmptyCard<R = Card>(\n now?: DateInput,\n afterHandler?: (card: Card) => R\n): R {\n const emptyCard: Card = {\n due: now ? TypeConvert.time(now) : new Date(),\n stability: 0,\n difficulty: 0,\n elapsed_days: 0,\n scheduled_days: 0,\n reps: 0,\n lapses: 0,\n learning_steps: 0,\n state: State.New,\n last_review: undefined,\n }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(emptyCard)\n } else {\n return emptyCard as R\n }\n}\n","// https://github.com/davidbau/seedrandom/blob/released/lib/alea.js\n// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010\n// http://baagoe.com/en/RandomMusings/javascript/\n// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror\n// Original work is under MIT license -\n\n// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\ntype State = {\n c: number\n s0: number\n s1: number\n s2: number\n}\n\nclass Alea {\n private c: number\n private s0: number\n private s1: number\n private s2: number\n\n constructor(seed?: number | string) {\n const mash = Mash()\n this.c = 1\n this.s0 = mash(' ')\n this.s1 = mash(' ')\n this.s2 = mash(' ')\n if (seed == null) seed = +new Date()\n this.s0 -= mash(seed)\n if (this.s0 < 0) this.s0 += 1\n this.s1 -= mash(seed)\n if (this.s1 < 0) this.s1 += 1\n this.s2 -= mash(seed)\n if (this.s2 < 0) this.s2 += 1\n }\n\n next(): number {\n const t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10 // 2^-32\n this.s0 = this.s1\n this.s1 = this.s2\n this.s2 = t - (this.c = t | 0)\n return this.s2\n }\n\n set state(state: State) {\n this.c = state.c\n this.s0 = state.s0\n this.s1 = state.s1\n this.s2 = state.s2\n }\n\n get state(): State {\n return {\n c: this.c,\n s0: this.s0,\n s1: this.s1,\n s2: this.s2,\n }\n }\n}\n\nfunction Mash() {\n let n = 0xefc8249d\n return function mash(data: string | number): number {\n data = String(data)\n for (let i = 0; i < data.length; i++) {\n n += data.charCodeAt(i)\n let h = 0.02519603282416938 * n\n n = h >>> 0\n h -= n\n h *= n\n n = h >>> 0\n h -= n\n n += h * 0x100000000 // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10 // 2^-32\n }\n}\n\nfunction alea(seed?: number | string) {\n const xg = new Alea(seed)\n const prng = () => xg.next()\n\n prng.int32 = () => (xg.next() * 0x100000000) | 0\n prng.double = () =>\n prng() + ((prng() * 0x200000) | 0) * 1.1102230246251565e-16 // 2^-53\n prng.state = () => xg.state\n prng.importState = (state: State) => {\n xg.state = state\n return prng\n }\n return prng\n}\n\nexport { alea }\n","import {\n clipParameters,\n generatorParameters,\n migrateParameters,\n} from './default'\nimport { FSRSParameters, FSRSState, Grade, Rating } from './models'\nimport type { int } from './types'\nimport { clamp, get_fuzz_range } from './help'\nimport { alea } from './alea'\nimport { S_MIN } from './constant'\n/**\n * $$\\text{decay} = -w_{20}$$\n *\n * $$\\text{factor} = e^{\\frac{\\ln 0.9}{\\text{decay}}} - 1$$\n */\nexport const computeDecayFactor = (\n decayOrParams: number | number[] | readonly number[]\n) => {\n const decay =\n typeof decayOrParams === 'number' ? -decayOrParams : -decayOrParams[20]\n const factor = Math.exp(Math.pow(decay, -1) * Math.log(0.9)) - 1.0\n return { decay, factor: +factor.toFixed(8) }\n}\n\n/**\n * The formula used is :\n * $$R(t,S) = (1 + \\text{FACTOR} \\times \\frac{t}{9 \\cdot S})^{\\text{DECAY}}$$\n * @param {number} elapsed_days t days since the last review\n * @param {number} stability Stability (interval when R=90%)\n * @return {number} r Retrievability (probability of recall)\n */\nexport function forgetting_curve(\n decay: number,\n elapsed_days: number,\n stability: number\n): number\nexport function forgetting_curve(\n parameters: number[] | readonly number[],\n elapsed_days: number,\n stability: number\n): number\nexport function forgetting_curve(\n decayOrParams: number | number[] | readonly number[],\n elapsed_days: number,\n stability: number\n): number {\n const { decay, factor } = computeDecayFactor(decayOrParams)\n return +Math.pow(1 + (factor * elapsed_days) / stability, decay).toFixed(8)\n}\n\n/**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm#fsrs-45\n */\nexport class FSRSAlgorithm {\n protected param!: FSRSParameters\n protected intervalModifier!: number\n protected _seed?: string\n\n constructor(params: Partial<FSRSParameters>) {\n this.param = new Proxy(\n generatorParameters(params),\n this.params_handler_proxy()\n )\n this.intervalModifier = this.calculate_interval_modifier(\n this.param.request_retention\n )\n this.forgetting_curve = forgetting_curve.bind(this, this.param.w)\n }\n\n get interval_modifier(): number {\n return this.intervalModifier\n }\n\n set seed(seed: string) {\n this._seed = seed\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm#fsrs-5\n *\n * The formula used is: $$I(r,s) = (r^{\\frac{1}{DECAY}} - 1) / FACTOR \\times s$$\n * @param request_retention 0<request_retention<=1,Requested retention rate\n * @throws {Error} Requested retention rate should be in the range (0,1]\n */\n calculate_interval_modifier(request_retention: number): number {\n if (request_retention <= 0 || request_retention > 1) {\n throw new Error('Requested retention rate should be in the range (0,1]')\n }\n const { decay, factor } = computeDecayFactor(this.param.w)\n return +((Math.pow(request_retention, 1 / decay) - 1) / factor).toFixed(8)\n }\n\n /**\n * Get the parameters of the algorithm.\n */\n get parameters(): FSRSParameters {\n return this.param\n }\n\n /**\n * Set the parameters of the algorithm.\n * @param params Partial<FSRSParameters>\n */\n set parameters(params: Partial<FSRSParameters>) {\n this.update_parameters(params)\n }\n\n protected params_handler_proxy(): ProxyHandler<FSRSParameters> {\n const _this = this satisfies FSRSAlgorithm\n return {\n set: function (\n target: FSRSParameters,\n prop: keyof FSRSParameters,\n value: FSRSParameters[keyof FSRSParameters]\n ) {\n if (prop === 'request_retention' && Number.isFinite(value)) {\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(value)\n )\n } else if (prop === 'w') {\n value = clipParameters(\n migrateParameters(value as FSRSParameters['w']),\n target.relearning_steps.length\n )\n _this.forgetting_curve = forgetting_curve.bind(this, value)\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(target.request_retention)\n )\n }\n Reflect.set(target, prop, value)\n return true\n },\n }\n }\n\n private update_parameters(params: Partial<FSRSParameters>): void {\n const _params = generatorParameters(params)\n for (const key in _params) {\n if (key in this.param) {\n const paramKey = key as keyof FSRSParameters\n this.param[paramKey] = _params[paramKey] as never\n }\n }\n }\n\n /**\n * The formula used is :\n * $$ S_0(G) = w_{G-1}$$\n * $$S_0 = \\max \\lbrace S_0,0.1\\rbrace $$\n\n * @param g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return Stability (interval when R=90%)\n */\n init_stability(g: Grade): number {\n return Math.max(this.param.w[g - 1], 0.1)\n }\n\n /**\n * The formula used is :\n * $$D_0(G) = w_4 - e^{(G-1) \\cdot w_5} + 1 $$\n * $$D_0 = \\min \\lbrace \\max \\lbrace D_0(G),1 \\rbrace,10 \\rbrace$$\n * where the $$D_0(1)=w_4$$ when the first rating is good.\n *\n * @param {Grade} g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return {number} Difficulty $$D \\in [1,10]$$\n */\n init_difficulty(g: Grade): number {\n const d = this.param.w[4] - Math.exp((g - 1) * this.param.w[5]) + 1\n return +d.toFixed(8)\n }\n\n /**\n * If fuzzing is disabled or ivl is less than 2.5, it returns the original interval.\n * @param {number} ivl - The interval to be fuzzed.\n * @param {number} elapsed_days t days since the last review\n * @return {number} - The fuzzed interval.\n **/\n apply_fuzz(ivl: number, elapsed_days: number): int {\n if (!this.param.enable_fuzz || ivl < 2.5) return Math.round(ivl) as int\n const generator = alea(this._seed) // I do not want others to directly access the seed externally.\n const fuzz_factor = generator()\n const { min_ivl, max_ivl } = get_fuzz_range(\n ivl,\n elapsed_days,\n this.param.maximum_interval\n )\n return Math.floor(fuzz_factor * (max_ivl - min_ivl + 1) + min_ivl) as int\n }\n\n /**\n * @see The formula used is : {@link FSRSAlgorithm.calculate_interval_modifier}\n * @param {number} s - Stability (interval when R=90%)\n * @param {number} elapsed_days t days since the last review\n */\n next_interval(s: number, elapsed_days: number): int {\n const newInterval = Math.min(\n Math.max(1, Math.round(s * this.intervalModifier)),\n this.param.maximum_interval\n ) as int\n return this.apply_fuzz(newInterval, elapsed_days)\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/issues/697\n */\n linear_damping(delta_d: number, old_d: number): number {\n return +((delta_d * (10 - old_d)) / 9).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$\\text{delta}_d = -w_6 \\cdot (g - 3)$$\n * $$\\text{next}_d = D + \\text{linear damping}(\\text{delta}_d , D)$$\n * $$D^\\prime(D,R) = w_7 \\cdot D_0(4) +(1 - w_7) \\cdot \\text{next}_d$$\n * @param {number} d Difficulty $$D \\in [1,10]$$\n * @param {Grade} g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return {number} $$\\text{next}_D$$\n */\n next_difficulty(d: number, g: Grade): number {\n const delta_d = -this.param.w[6] * (g - 3)\n const next_d = d + this.linear_damping(delta_d, d)\n return clamp(\n this.mean_reversion(this.init_difficulty(Rating.Easy), next_d),\n 1,\n 10\n )\n }\n\n /**\n * The formula used is :\n * $$w_7 \\cdot \\text{init} +(1 - w_7) \\cdot \\text{current}$$\n * @param {number} init $$w_2 : D_0(3) = w_2 + (R-2) \\cdot w_3= w_2$$\n * @param {number} current $$D - w_6 \\cdot (R - 2)$$\n * @return {number} difficulty\n */\n mean_reversion(init: number, current: number): number {\n return +(this.param.w[7] * init + (1 - this.param.w[7]) * current).toFixed(\n 8\n )\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_r(D,S,R,G) = S\\cdot(e^{w_8}\\cdot (11-D)\\cdot S^{-w_9}\\cdot(e^{w_{10}\\cdot(1-R)}-1)\\cdot w_{15}(\\text{if} G=2) \\cdot w_{16}(\\text{if} G=4)+1)$$\n * @param {number} d Difficulty D \\in [1,10]\n * @param {number} s Stability (interval when R=90%)\n * @param {number} r Retrievability (probability of recall)\n * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])\n * @return {number} S^\\prime_r new stability after recall\n */\n next_recall_stability(d: number, s: number, r: number, g: Grade): number {\n const hard_penalty = Rating.Hard === g ? this.param.w[15] : 1\n const easy_bound = Rating.Easy === g ? this.param.w[16] : 1\n return +clamp(\n s *\n (1 +\n Math.exp(this.param.w[8]) *\n (11 - d) *\n Math.pow(s, -this.param.w[9]) *\n (Math.exp((1 - r) * this.param.w[10]) - 1) *\n hard_penalty *\n easy_bound),\n S_MIN,\n 36500.0\n ).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_f(D,S,R) = w_{11}\\cdot D^{-w_{12}}\\cdot ((S+1)^{w_{13}}-1) \\cdot e^{w_{14}\\cdot(1-R)}$$\n * enable_short_term = true : $$S^\\prime_f \\in \\min \\lbrace \\max \\lbrace S^\\prime_f,0.01\\rbrace, \\frac{S}{e^{w_{17} \\cdot w_{18}}} \\rbrace$$\n * enable_short_term = false : $$S^\\prime_f \\in \\min \\lbrace \\max \\lbrace S^\\prime_f,0.01\\rbrace, S \\rbrace$$\n * @param {number} d Difficulty D \\in [1,10]\n * @param {number} s Stability (interval when R=90%)\n * @param {number} r Retrievability (probability of recall)\n * @return {number} S^\\prime_f new stability after forgetting\n */\n next_forget_stability(d: number, s: number, r: number): number {\n return +clamp(\n this.param.w[11] *\n Math.pow(d, -this.param.w[12]) *\n (Math.pow(s + 1, this.param.w[13]) - 1) *\n Math.exp((1 - r) * this.param.w[14]),\n S_MIN,\n 36500.0\n ).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_s(S,G) = S \\cdot e^{w_{17} \\cdot (G-3+w_{18})}$$\n * @param {number} s Stability (interval when R=90%)\n * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])\n */\n next_short_term_stability(s: number, g: Grade): number {\n const sinc =\n Math.pow(s, -this.param.w[19]) *\n Math.exp(this.param.w[17] * (g - 3 + this.param.w[18]))\n\n const maskedSinc = g >= 3 ? Math.max(sinc, 1.0) : sinc\n return +clamp(s * maskedSinc, S_MIN, 36500.0).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$R(t,S) = (1 + \\text{FACTOR} \\times \\frac{t}{9 \\cdot S})^{\\text{DECAY}}$$\n * @param {number} elapsed_days t days since the last review\n * @param {number} stability Stability (interval when R=90%)\n * @return {number} r Retrievability (probability of recall)\n */\n forgetting_curve: (elapsed_days: number, stability: number) => number\n /**\n * Calculates the next state of memory based on the current state, time elapsed, and grade.\n *\n * @param memory_state - The current state of memory, which can be null.\n * @param t - The time elapsed since the last review.\n * @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])\n * @returns The next state of memory with updated difficulty and stability.\n */\n next_state(memory_state: FSRSState | null, t: number, g: number): FSRSState {\n const { difficulty: d, stability: s } = memory_state ?? {\n difficulty: 0,\n stability: 0,\n }\n if (t < 0) {\n throw new Error(`Invalid delta_t \"${t}\"`)\n }\n if (g < 0 || g > 4) {\n throw new Error(`Invalid grade \"${g}\"`)\n }\n if (d === 0 && s === 0) {\n return {\n difficulty: clamp(this.init_difficulty(g), 1, 10),\n stability: this.init_stability(g),\n }\n }\n if (g === 0) {\n return {\n difficulty: d,\n stability: s,\n }\n }\n if (d < 1 || s < S_MIN) {\n throw new Error(\n `Invalid memory state { difficulty: ${d}, stability: ${s} }`\n )\n }\n const r = this.forgetting_curve(t, s)\n const s_after_success = this.next_recall_stability(d, s, r, g)\n const s_after_fail = this.next_forget_stability(d, s, r)\n const s_after_short_term = this.next_short_term_stability(s, g)\n let new_s = s_after_success\n if (g === 1) {\n let [w_17, w_18] = [0, 0]\n if (this.param.enable_short_term) {\n w_17 = this.param.w[17]\n w_18 = this.param.w[18]\n }\n const next_s_min = s / Math.exp(w_17 * w_18)\n new_s = clamp(+next_s_min.toFixed(8), S_MIN, s_after_fail)\n }\n if (t === 0 && this.param.enable_short_term) {\n new_s = s_after_short_term\n }\n\n const new_d = this.next_difficulty(d, g)\n return { difficulty: new_d, stability: new_s }\n }\n}\n","import type { AbstractScheduler } from '../abstract_scheduler'\nimport type { TSeedStrategy } from './types'\n\nexport function DefaultInitSeedStrategy(this: AbstractScheduler): string {\n const time = this.review_time.getTime()\n const reps = this.current.reps\n const mul = this.current.difficulty * this.current.stability\n return `${time}_${reps}_${mul}`\n}\n\n/**\n * Generates a seed strategy function for card IDs.\n *\n * @param card_id_field - The field name of the card ID in the current object.\n * @returns A function that generates a seed based on the card ID and repetitions.\n *\n * @remarks\n * The returned function uses the `card_id_field` to retrieve the card ID from the current object.\n * It then adds the number of repetitions (`reps`) to the card ID to generate the seed.\n *\n * @example\n * ```typescript\n * const seedStrategy = GenCardIdSeedStrategy('card_id');\n * const f = fsrs().useStrategy(StrategyMode.SEED, seedStrategy)\n * const card = createEmptyCard<Card & { card_id: number }>()\n * card.card_id = 555\n * const record = f.repeat(card, new Date())\n * ```\n */\nexport function GenSeedStrategyWithCardId(\n card_id_field: string | number\n): TSeedStrategy {\n return function (this: AbstractScheduler): string {\n // https://github.com/open-spaced-repetition/ts-fsrs/issues/131#issuecomment-2408426225\n const card_id = Reflect.get(this.current, card_id_field) ?? 0\n const reps = this.current.reps\n // ex1\n // card_id:string + reps:number = 'e2ecb1f7-8d15-420b-bec4-c7212ad2e5dc' + 4\n // = 'e2ecb1f7-8d15-420b-bec4-c7212ad2e5dc4'\n\n // ex2\n // card_id:number + reps:number = 1732452519198 + 4\n // = '17324525191984'\n return String(card_id + reps || 0)\n }\n}\n","import { FSRSParameters, Rating, State, StepUnit, TimeUnit } from '../models'\nimport { TLearningStepsStrategy } from './types'\n\nexport const ConvertStepUnitToMinutes = (step: StepUnit): number => {\n const unit = step.slice(-1) as TimeUnit\n const value = parseInt(step.slice(0, -1), 10)\n if (isNaN(value) || !Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid step value: ${step}`)\n }\n switch (unit) {\n case 'm':\n return value\n case 'h':\n return value * 60\n case 'd':\n return value * 1440\n default:\n throw new Error(`Invalid step unit: ${step}, expected m/h/d`)\n }\n}\n\nexport const BasicLearningStepsStrategy: TLearningStepsStrategy = (\n params: FSRSParameters,\n state: State,\n cur_step: number\n) => {\n const learning_steps =\n state === State.Relearning || state === State.Review\n ? params.relearning_steps\n : params.learning_steps\n const steps_length = learning_steps.length\n // steps_length === 0 ,return empty object\n if (steps_length === 0 || cur_step >= steps_length) return {}\n\n // steps_length > 0\n const firstStep = learning_steps[0]\n\n const toMinutes = ConvertStepUnitToMinutes\n\n const getAgainInterval = (): number => {\n return toMinutes(firstStep)\n }\n\n const getHardInterval = (): number => {\n // steps_length > 0,return firstStep*1.5\n if (steps_length === 1) return Math.round(toMinutes(firstStep) * 1.5)\n // steps_length > 1,return (firstStep+nextStep)/2\n const nextStep = learning_steps[1]\n return Math.round((toMinutes(firstStep) + toMinutes(nextStep)) / 2)\n }\n\n const getStepInfo = (index: number) => {\n if (index < 0 || index >= steps_length) {\n return null\n } else {\n return learning_steps[index]\n }\n }\n\n const getGoodMinutes = (step: StepUnit): number | null => {\n return toMinutes(step)\n }\n\n const result: ReturnType<TLearningStepsStrategy> = {}\n const step_info = getStepInfo(Math.max(0, cur_step))\n // review -> again\n // new, learning, relearning -> again,hard,good(if next step exists)\n if (state === State.Review) {\n // review\n result[Rating.Again] = {\n scheduled_minutes: toMinutes(step_info!),\n next_step: 0,\n }\n return result\n } else {\n // new,learning, relearning\n result[Rating.Again] = {\n scheduled_minutes: getAgainInterval(),\n next_step: 0,\n }\n\n result[Rating.Hard] = {\n scheduled_minutes: getHardInterval(),\n next_step: cur_step,\n }\n const next_info = getStepInfo(cur_step + 1)\n if (next_info) {\n const nextMin = getGoodMinutes(next_info)\n\n if (nextMin) {\n result[Rating.Good] = {\n scheduled_minutes: Math.round(nextMin),\n next_step: cur_step + 1,\n }\n }\n }\n }\n return result\n}\n","import type { AbstractScheduler } from '../abstract_scheduler'\nimport type { FSRSAlgorithm } from '../algorithm'\nimport type {\n Card,\n CardInput,\n DateInput,\n FSRSParameters,\n Grade,\n State,\n} from '../models'\nimport type { IScheduler } from '../types'\n\nexport enum StrategyMode {\n SCHEDULER = 'Scheduler',\n LEARNING_STEPS = 'LearningSteps',\n SEED = 'Seed',\n}\n\nexport type TSeedStrategy = (this: AbstractScheduler) => string\nexport type TSchedulerStrategy<T extends CardInput | Card = CardInput | Card> =\n new (\n card: T,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies: Map<StrategyMode, TStrategyHandler>\n ) => IScheduler\n\n/**\n * When enable_short_term = false, the learning steps strategy will not take effect.\n */\nexport type TLearningStepsStrategy = (\n params: FSRSParameters,\n state: State,\n cur_step: number\n) => {\n [K in Grade]?: { scheduled_minutes: number; next_step: number }\n}\n\ntype StrategyMap = {\n [StrategyMode.SCHEDULER]: TSchedulerStrategy\n [StrategyMode.SEED]: TSeedStrategy\n [StrategyMode.LEARNING_STEPS]: TLearningStepsStrategy\n}\n\nexport type TStrategyHandler<E = StrategyMode> = E extends StrategyMode\n ? StrategyMap[E]\n : never\n","import { FSRSAlgorithm } from './algorithm'\nimport { TypeConvert } from './convert'\nimport { dateDiffInDays, Grades } from './help'\nimport {\n type Card,\n type Grade,\n type RecordLogItem,\n State,\n Rating,\n type ReviewLog,\n type CardInput,\n type DateInput,\n} from './models'\nimport { DefaultInitSeedStrategy } from './strategies'\nimport {\n StrategyMode,\n TSeedStrategy,\n TStrategyHandler,\n} from './strategies/types'\nimport type { IPreview, IScheduler } from './types'\n\nexport abstract class AbstractScheduler implements IScheduler {\n protected last: Card\n protected current: Card\n protected review_time: Date\n protected next: Map<Grade, RecordLogItem> = new Map()\n protected algorithm: FSRSAlgorithm\n protected strategies: Map<StrategyMode, TStrategyHandler> | undefined\n protected elapsed_days: number = 0 // init\n\n constructor(\n card: CardInput | Card,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies?: Map<StrategyMode, TStrategyHandler>\n ) {\n this.algorithm = algorithm\n this.last = TypeConvert.card(card)\n this.current = TypeConvert.card(card)\n this.review_time = TypeConvert.time(now)\n this.strategies = strategies\n this.init()\n }\n\n protected checkGrade(grade: Grade): void {\n if (!Number.isFinite(grade) || grade < 0 || grade > 4) {\n throw new Error(`Invalid grade \"${grade}\",expected 1-4`)\n }\n }\n\n private init() {\n const { state, last_review } = this.current\n let interval = 0 // card.state === State.New => 0\n if (state !== State.New && last_review) {\n interval = dateDiffInDays(last_review, this.review_time)\n }\n this.current.last_review = this.review_time\n this.elapsed_days = interval\n // pending removal in v6.0.0\n this.current.elapsed_days = interval\n this.current.reps += 1\n\n // init seed strategy\n let seed_strategy = DefaultInitSeedStrategy\n if (this.strategies) {\n const custom_strategy = this.strategies.get(StrategyMode.SEED)\n if (custom_strategy) {\n seed_strategy = custom_strategy as TSeedStrategy\n }\n }\n this.algorithm.seed = (<TSeedStrategy>seed_strategy).call(this)\n }\n\n public preview(): IPreview {\n return {\n [Rating.Again]: this.review(Rating.Again),\n [Rating.Hard]: this.review(Rating.Hard),\n [Rating.Good]: this.review(Rating.Good),\n [Rating.Easy]: this.review(Rating.Easy),\n [Symbol.iterator]: this.previewIterator.bind(this),\n } satisfies IPreview\n }\n\n private *previewIterator(): IterableIterator<RecordLogItem> {\n for (const grade of Grades) {\n yield this.review(grade)\n }\n }\n\n public review(grade: Grade): RecordLogItem {\n const { state } = this.last\n let item: RecordLogItem | undefined\n this.checkGrade(grade)\n switch (state) {\n case State.New:\n item = this.newState(grade)\n break\n case State.Learning:\n case State.Relearning:\n item = this.learningState(grade)\n break\n case State.Review:\n item = this.reviewState(grade)\n break\n }\n return item\n }\n\n protected abstract newState(grade: Grade): RecordLogItem\n\n protected abstract learningState(grade: Grade): RecordLogItem\n\n protected abstract reviewState(grade: Grade): RecordLogItem\n\n protected buildLog(rating: Grade): ReviewLog {\n const { last_review, due, elapsed_days } = this.last\n\n return {\n rating: rating,\n state: this.current.state,\n due: last_review || due,\n stability: this.current.stability,\n difficulty: this.current.difficulty,\n elapsed_days: this.elapsed_days,\n last_elapsed_days: elapsed_days,\n scheduled_days: this.current.scheduled_days,\n learning_steps: this.current.learning_steps,\n review: this.review_time,\n } satisfies ReviewLog\n }\n}\n","import { AbstractScheduler } from '../abstract_scheduler'\nimport { TypeConvert } from '../convert'\nimport { S_MIN } from '../constant'\nimport { clamp, date_scheduler } from '../help'\nimport {\n type Card,\n CardInput,\n DateInput,\n type Grade,\n Rating,\n type RecordLogItem,\n State,\n} from '../models'\nimport type { int } from '../types'\nimport {\n StrategyMode,\n TLearningStepsStrategy,\n TStrategyHandler,\n} from '../strategies'\nimport { FSRSAlgorithm } from '../algorithm'\nimport { BasicLearningStepsStrategy } from '../strategies/learning_steps'\n\nexport default class BasicScheduler extends AbstractScheduler {\n private learningStepsStrategy: TLearningStepsStrategy\n\n constructor(\n card: CardInput | Card,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies?: Map<StrategyMode, TStrategyHandler>\n ) {\n super(card, now, algorithm, strategies)\n\n // init learning steps strategy\n let learningStepStrategy = BasicLearningStepsStrategy\n if (this.strategies) {\n const custom_strategy = this.strategies.get(StrategyMode.LEARNING_STEPS)\n if (custom_strategy) {\n learningStepStrategy = custom_strategy as TLearningStepsStrategy\n }\n }\n this.learningStepsStrategy = learningStepStrategy\n }\n\n private getLearningInfo(card: Card, grade: Grade) {\n const parameters = this.algorithm.parameters\n card.learning_steps = card.learning_steps || 0\n const steps_strategy = this.learningStepsStrategy(\n parameters,\n card.state,\n // In the original learning steps setup (Again = 5m, Hard = 10m, Good = FSRS),\n // not adding 1 can cause slight variations in the memory state’s ds.\n this.current.state === State.Learning\n ? card.learning_steps + 1\n : card.learning_steps\n )\n const scheduled_minutes = Math.max(\n 0,\n steps_strategy[grade]?.scheduled_minutes ?? 0\n )\n const next_steps = Math.max(0, steps_strategy[grade]?.next_step ?? 0)\n return {\n scheduled_minutes,\n next_steps,\n }\n }\n /**\n * @description This function applies the learning steps based on the current card's state and grade.\n */\n private applyLearningSteps(\n nextCard: Card,\n grade: Grade,\n /**\n * returns the next state for the card (if applicable)\n */\n to_state: State\n ) {\n const { scheduled_minutes, next_steps } = this.getLearningInfo(\n this.current,\n grade\n )\n if (\n scheduled_minutes > 0 &&\n scheduled_minutes < 1440 /** 1440 minutes = 1 day */\n ) {\n nextCard.learning_steps = next_steps\n nextCard.scheduled_days = 0\n nextCard.state = to_state\n nextCard.due = date_scheduler(\n this.review_time,\n Math.round(scheduled_minutes) as int,\n false /** true:days false: minute */\n )\n } else {\n nextCard.state = State.Review\n if (scheduled_minutes >= 1440) {\n nextCard.learning_steps = next_steps\n nextCard.due = date_scheduler(\n this.review_time,\n Math.round(scheduled_minutes) as int,\n false /** true:days false: minute */\n )\n nextCard.scheduled_days = Math.floor(scheduled_minutes / 1440)\n } else {\n nextCard.learning_steps = 0\n const interval = this.algorithm.next_interval(\n nextCard.stability,\n this.elapsed_days\n )\n nextCard.scheduled_days = interval\n nextCard.due = date_scheduler(this.review_time, interval as int, true)\n }\n }\n }\n\n protected override newState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const next = TypeConvert.card(this.current)\n next.difficulty = clamp(this.algorithm.init_difficulty(grade), 1, 10)\n next.stability = this.algorithm.init_stability(grade)\n\n this.applyLearningSteps(next, grade, State.Learning)\n const item = {\n card: next,\n log: this.buildLog(grade),\n } satisfies RecordLogItem\n this.next.set(grade, item)\n return item\n }\n\n protected override learningState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const { state, difficulty, stability } = this.last\n const next = TypeConvert.card(this.current)\n next.difficulty = this.algorithm.next_difficulty(difficulty, grade)\n next.stability = this.algorithm.next_short_term_stability(stability, grade)\n this.applyLearningSteps(next, grade, state /** Learning or Relearning */)\n const item = {\n card: next,\n log: this.buildLog(grade),\n } satisfies RecordLogItem\n this.next.set(grade, item)\n return item\n }\n\n protected override reviewState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const interval = this.elapsed_days\n const { difficulty, stability } = this.last\n const retrievability = this.algorithm.forgetting_curve(interval, stability)\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.next_ds(\n next_again,\n next_hard,\n next_good,\n next_easy,\n difficulty,\n stability,\n retrievability\n )\n\n this.next_interval(next_hard, next_good, next_easy, interval)\n this.next_state(next_hard, next_good, next_easy)\n this.applyLearningSteps(next_again, Rating.Again, State.Relearning)\n next_again.lapses += 1\n\n const item_again = {\n card: next_again,\n log: this.buildLog(Rating.Again),\n } satisfies RecordLogItem\n const item_hard = {\n card: next_hard,\n log: super.buildLog(Rating.Hard),\n } satisfies RecordLogItem\n const item_good = {\n card: next_good,\n log: super.buildLog(Rating.Good),\n } satisfies RecordLogItem\n const item_easy = {\n card: next_easy,\n log: super.buildLog(Rating.Easy),\n } satisfies RecordLogItem\n\n this.next.set(Rating.Again, item_again)\n this.next.set(Rating.Hard, item_hard)\n this.next.set(Rating.Good, item_good)\n this.next.set(Rating.Easy, item_easy)\n return this.next.get(grade)!\n }\n\n /**\n * Review next_ds\n */\n private next_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n difficulty: number,\n stability: number,\n retrievability: number\n ): void {\n next_again.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Again\n )\n const nextSMin =\n stability /\n Math.exp(\n this.algorithm.parameters.w[17] * this.algorithm.parameters.w[18]\n )\n const s_after_fail = this.algorithm.next_forget_stability(\n difficulty,\n stability,\n retrievability\n )\n next_again.stability = clamp(+nextSMin.toFixed(8), S_MIN, s_after_fail)\n\n next_hard.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Hard\n )\n next_hard.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Hard\n )\n next_good.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Good\n )\n next_good.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Good\n )\n next_easy.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Easy\n )\n next_easy.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Easy\n )\n }\n\n /**\n * Review next_interval\n */\n private next_interval(\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n interval: number\n ): void {\n let hard_interval: int, good_interval: int\n hard_interval = this.algorithm.next_interval(next_hard.stability, interval)\n good_interval = this.algorithm.next_interval(next_good.stability, interval)\n hard_interval = Math.min(hard_interval, good_interval) as int\n good_interval = Math.max(good_interval, hard_interval + 1) as int\n const easy_interval = Math.max(\n this.algorithm.next_interval(next_easy.stability, interval),\n good_interval + 1\n ) as int\n\n next_hard.scheduled_days = hard_interval\n next_hard.due = date_scheduler(this.review_time, hard_interval, true)\n next_good.scheduled_days = good_interval\n next_good.due = date_scheduler(this.review_time, good_interval, true)\n\n next_easy.scheduled_days = easy_interval\n next_easy.due = date_scheduler(this.review_time, easy_interval, true)\n }\n\n /**\n * Review next_state\n */\n private next_state(next_hard: Card, next_good: Card, next_easy: Card) {\n next_hard.state = State.Review\n next_hard.learning_steps = 0\n\n next_good.state = State.Review\n next_good.learning_steps = 0\n\n next_easy.state = State.Review\n next_easy.learning_steps = 0\n }\n}\n","import { AbstractScheduler } from '../abstract_scheduler'\nimport { TypeConvert } from '../convert'\nimport { S_MIN } from '../constant'\nimport { clamp, date_scheduler } from '../help'\nimport {\n type Card,\n type Grade,\n Rating,\n type RecordLogItem,\n State,\n} from '../models'\nimport type { int } from '../types'\n\nexport default class LongTermScheduler extends AbstractScheduler {\n protected override newState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n\n this.current.scheduled_days = 0\n // pending removal in v6.0.0\n this.current.elapsed_days = 0\n\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.init_ds(next_again, next_hard, next_good, next_easy)\n const first_interval = 0\n\n this.next_interval(\n next_again,\n next_hard,\n next_good,\n next_easy,\n first_interval\n )\n\n this.next_state(next_again, next_hard, next_good, next_easy)\n this.update_next(next_again, next_hard, next_good, next_easy)\n return this.next.get(grade)!\n }\n\n private init_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ): void {\n next_again.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Again),\n 1,\n 10\n )\n next_again.stability = this.algorithm.init_stability(Rating.Again)\n\n next_hard.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Hard),\n 1,\n 10\n )\n next_hard.stability = this.algorithm.init_stability(Rating.Hard)\n\n next_good.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Good),\n 1,\n 10\n )\n next_good.stability = this.algorithm.init_stability(Rating.Good)\n\n next_easy.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Easy),\n 1,\n 10\n )\n next_easy.stability = this.algorithm.init_stability(Rating.Easy)\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/ts-fsrs/issues/98#issuecomment-2241923194\n */\n protected override learningState(grade: Grade): RecordLogItem {\n return this.reviewState(grade)\n }\n protected override reviewState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const interval = this.elapsed_days\n const { difficulty, stability } = this.last\n const retrievability = this.algorithm.forgetting_curve(interval, stability)\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.next_ds(\n next_again,\n next_hard,\n next_good,\n next_easy,\n difficulty,\n stability,\n retrievability\n )\n\n this.next_interval(next_again, next_hard, next_good, next_easy, interval)\n this.next_state(next_again, next_hard, next_good, next_easy)\n next_again.lapses += 1\n\n this.update_next(next_again, next_hard, next_good, next_easy)\n return this.next.get(grade)!\n }\n\n /**\n * Review next_ds\n */\n private next_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n difficulty: number,\n stability: number,\n retrievability: number\n ): void {\n next_again.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Again\n )\n const s_after_fail = this.algorithm.next_forget_stability(\n difficulty,\n stability,\n retrievability\n )\n next_again.stability = clamp(stability, S_MIN, s_after_fail)\n\n next_hard.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Hard\n )\n next_hard.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Hard\n )\n next_good.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Good\n )\n next_good.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Good\n )\n next_easy.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Easy\n )\n next_easy.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Easy\n )\n }\n\n /**\n * Review/New next_interval\n */\n private next_interval(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n interval: number\n ): void {\n let again_interval: int,\n hard_interval: int,\n good_interval: int,\n easy_interval: int\n again_interval = this.algorithm.next_interval(\n next_again.stability,\n interval\n )\n hard_interval = this.algorithm.next_interval(next_hard.stability, interval)\n good_interval = this.algorithm.next_interval(next_good.stability, interval)\n easy_interval = this.algorithm.next_interval(next_easy.stability, interval)\n\n again_interval = Math.min(again_interval, hard_interval) as int\n hard_interval = Math.max(hard_interval, again_interval + 1) as int\n good_interval = Math.max(good_interval, hard_interval + 1) as int\n easy_interval = Math.max(easy_interval, good_interval + 1) as int\n\n next_again.scheduled_days = again_interval\n next_again.due = date_scheduler(this.review_time, again_interval, true)\n\n next_hard.scheduled_days = hard_interval\n next_hard.due = date_scheduler(this.review_time, hard_interval, true)\n\n next_good.scheduled_days = good_interval\n next_good.due = date_scheduler(this.review_time, good_interval, true)\n\n next_easy.scheduled_days = easy_interval\n next_easy.due = date_scheduler(this.review_time, easy_interval, true)\n }\n\n /**\n * Review/New next_state\n */\n private next_state(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ) {\n next_again.state = State.Review\n // next_again.lapses += 1\n next_again.learning_steps = 0\n\n next_hard.state = State.Review\n next_hard.learning_steps = 0\n\n next_good.state = State.Review\n next_good.learning_steps = 0\n\n next_easy.state = State.Review\n next_easy.learning_steps = 0\n }\n\n private update_next(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ) {\n const item_again = {\n card: next_again,\n log: this.buildLog(Rating.Again),\n } satisfies RecordLogItem\n const item_hard = {\n card: next_hard,\n log: super.buildLog(Rating.Hard),\n } satisfies RecordLogItem\n const item_good = {\n card: next_good,\n log: super.buildLog(Rating.Good),\n } satisfies RecordLogItem\n const item_easy = {\n card: next_easy,\n log: super.buildLog(Rating.Easy),\n } satisfies RecordLogItem\n\n this.next.set(Rating.Again, item_again)\n this.next.set(Rating.Hard, item_hard)\n this.next.set(Rating.Good, item_good)\n this.next.set(Rating.Easy, item_easy)\n }\n}\n","import { TypeConvert } from './convert'\nimport { createEmptyCard } from './default'\nimport type { FSRS } from './fsrs'\nimport { date_diff } from './help'\nimport {\n type Card,\n type CardInput,\n DateInput,\n type FSRSHistory,\n type Grade,\n Rating,\n type RecordLogItem,\n type ReviewLog,\n State,\n} from './models'\n\n/**\n * The `Reschedule` class provides methods to handle the rescheduling of cards based on their review history.\n * determine the next review dates and update the card's state accordingly.\n */\nexport class Reschedule {\n private fsrs: FSRS\n /**\n * Creates an instance of the `Reschedule` class.\n * @param fsrs - An instance of the FSRS class used for scheduling.\n */\n constructor(fsrs: FSRS) {\n this.fsrs = fsrs\n }\n\n /**\n * Replays a review for a card and determines the next review date based on the given rating.\n * @param card - The card being reviewed.\n * @param reviewed - The date the card was reviewed.\n * @param rating - The grade given to the card during the review.\n * @returns A `RecordLogItem` containing the updated card and review log.\n */\n replay(card: Card, reviewed: Date, rating: Grade): RecordLogItem {\n return this.fsrs.next(card, reviewed, rating)\n }\n\n /**\n * Processes a manual review for a card, allowing for custom state, stability, difficulty, and due date.\n * @param card - The card being reviewed.\n * @param state - The state of the card after the review.\n * @param reviewed - The date the card was reviewed.\n * @param elapsed_days - The number of days since the last review.\n * @param stability - (Optional) The stability of the card.\n * @param difficulty - (Optional) The difficulty of the card.\n * @param due - (Optional) The due date for the next review.\n * @returns A `RecordLogItem` containing the updated card and review log.\n * @throws Will throw an error if the state or due date is not provided when required.\n */\n handleManualRating(\n card: Card,\n state: State,\n reviewed: Date,\n elapsed_days: number,\n stability?: number,\n difficulty?: number,\n due?: Date\n ): RecordLogItem {\n if (typeof state === 'undefined') {\n throw new Error('reschedule: state is required for manual rating')\n }\n let log: ReviewLog\n let next_card: Card\n if (<State>state === State.New) {\n log = {\n rating: Rating.Manual,\n state: state,\n due: <Date>due ?? reviewed,\n stability: card.stability,\n difficulty: card.difficulty,\n elapsed_days: elapsed_days,\n last_elapsed_days: card.elapsed_days,\n scheduled_days: card.scheduled_days,\n learning_steps: card.learning_steps,\n review: <Date>reviewed,\n } satisfies ReviewLog\n next_card = createEmptyCard<Card>(reviewed)\n next_card.last_review = reviewed\n } else {\n if (typeof due === 'undefined') {\n throw new Error('reschedule: due is required for manual rating')\n }\n const scheduled_days = date_diff(due, reviewed, 'days')\n log = {\n rating: Rating.Manual,\n state: <State>card.state,\n due: card.last_review || card.due,\n stability: card.stability,\n difficulty: card.difficulty,\n elapsed_days: elapsed_days,\n last_elapsed_days: card.elapsed_days,\n scheduled_days: card.scheduled_days,\n learning_steps: card.learning_steps,\n review: <Date>reviewed,\n } satisfies ReviewLog\n next_card = {\n ...card,\n state: <State>state,\n due: <Date>due,\n last_review: <Date>reviewed,\n stability: stability || card.stability,\n difficulty: difficulty || card.difficulty,\n elapsed_days: elapsed_days,\n scheduled_days: scheduled_days,\n reps: card.reps + 1,\n } satisfies Card\n }\n\n return { card: next_card, log }\n }\n\n /**\n * Reschedules a card based on its review history.\n *\n * @param current_card - The card to be rescheduled.\n * @param reviews - An array of review history objects.\n * @returns An array of record log items representing the rescheduling process.\n */\n reschedule(current_card: CardInput, reviews: FSRSHistory[]) {\n const collections: RecordLogItem[] = []\n let cur_card = createEmptyCard<Card>(current_card.due)\n for (const review of reviews) {\n let item: RecordLogItem\n review.review = TypeConvert.time(review.review)\n if (review.rating === Rating.Manual) {\n // ref: abstract_scheduler.ts#init\n let interval = 0\n if (cur_card.state !== State.New && cur_card.last_review) {\n interval = date_diff(review.review, cur_card.last_review, 'days')\n }\n item = this.handleManualRating(\n cur_card,\n review.state,\n review.review,\n interval,\n review.stability,\n review.difficulty,\n review.due ? TypeConvert.time(review.due) : undefined\n )\n } else {\n item = this.replay(cur_card, review.review, review.rating)\n }\n collections.push(item)\n cur_card = item.card\n }\n return collections\n }\n\n calculateManualRecord(\n current_card: CardInput,\n now: DateInput,\n record_log_item?: RecordLogItem,\n update_memory?: boolean\n ): RecordLogItem | null {\n if (!record_log_item) {\n return null\n }\n // if first_card === recordItem.card then return null\n const { card: reschedule_card, log } = record_log_item\n const cur_card = <Card>TypeConvert.card(current_card) // copy card\n if (cur_card.due.getTime() === reschedule_card.due.getTime()) {\n return null\n }\n cur_card.scheduled_days = date_diff(\n reschedule_card.due,\n cur_card.due,\n 'days'\n )\n return this.handleManualRating(\n cur_card,\n reschedule_card.state,\n TypeConvert.time(now),\n log.elapsed_days,\n update_memory ? reschedule_card.stability : undefined,\n update_memory ? reschedule_card.difficulty : undefined,\n reschedule_card.due\n )\n }\n}\n","import {\n Card,\n CardInput,\n DateInput,\n FSRSHistory,\n FSRSParameters,\n Grade,\n Rating,\n RecordLogItem,\n ReviewLog,\n ReviewLogInput,\n State,\n} from './models'\nimport {\n type IPreview,\n type IReschedule,\n type RescheduleOptions,\n type IScheduler,\n} from './types'\nimport { forgetting_curve, FSRSAlgorithm } from './algorithm'\nimport { TypeConvert } from './convert'\nimport BasicScheduler from './impl/basic_scheduler'\nimport LongTermScheduler from './impl/long_term_scheduler'\nimport { clipParameters, createEmptyCard, migrateParameters } from './default'\nimport { Reschedule } from './reschedule'\nimport {\n StrategyMode,\n type TSchedulerStrategy,\n type TStrategyHandler,\n} from './strategies/types'\nimport { date_diff } from './help'\n\n// A utility type to require only K properties of A\ntype RequireOnly<A, K extends keyof A> = { [P in K]-?: A[P] } & Partial<\n Omit<A, K>\n>\n\nexport interface IFSRS {\n useStrategy<T extends StrategyMode>(\n mode: T,\n handler: TStrategyHandler<T>\n ): this\n\n clearStrategy(mode?: StrategyMode): this\n\n repeat(card: CardInput | Card, now: DateInput): IPreview\n repeat<R>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler: (recordLog: IPreview) => R\n ): R\n\n next(card: CardInput | Card, now: DateInput, grade: Grade): RecordLogItem\n next<R>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler: (recordLog: RecordLogItem) => R\n ): R\n\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: true\n ): string\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: false\n ): number\n\n rollback(card: CardInput | Card, log: ReviewLogInput): Card\n rollback<R>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler: (prevCard: Card) => R\n ): R\n\n forget(\n card: CardInput | Card,\n now: DateInput,\n reset_count?: boolean\n ): RecordLogItem\n forget<R>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean | undefined,\n afterHandler: (recordLogItem: RecordLogItem) => R\n ): R\n\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: RequireOnly<RescheduleOptions<T>, 'recordLogHandler'>\n ): IReschedule<T>\n reschedule(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: Partial<RescheduleOptions<RecordLogItem>>\n ): IReschedule<RecordLogItem>\n}\n\nexport class FSRS extends FSRSAlgorithm implements IFSRS {\n private strategyHandler = new Map<StrategyMode, TStrategyHandler>()\n private Scheduler: TSchedulerStrategy\n constructor(param: Partial<FSRSParameters>) {\n super(param)\n const { enable_short_term } = this.parameters\n this.Scheduler = enable_short_term ? BasicScheduler : LongTermScheduler\n }\n\n protected override params_handler_proxy(): ProxyHandler<FSRSParameters> {\n const _this = this satisfies FSRS\n return {\n set: function (\n target: FSRSParameters,\n prop: keyof FSRSParameters,\n value: FSRSParameters[keyof FSRSParameters]\n ) {\n if (prop === 'request_retention' && Number.isFinite(value)) {\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(value)\n )\n } else if (prop === 'enable_short_term') {\n _this.Scheduler = value === true ? BasicScheduler : LongTermScheduler\n } else if (prop === 'w') {\n value = clipParameters(\n migrateParameters(value as FSRSParameters['w']),\n target.relearning_steps.length\n )\n _this.forgetting_curve = forgetting_curve.bind(this, value)\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(target.request_retention)\n )\n }\n Reflect.set(target, prop, value)\n return true\n },\n }\n }\n\n useStrategy<T extends StrategyMode>(\n mode: T,\n handler: TStrategyHandler<T>\n ): this {\n this.strategyHandler.set(mode, handler)\n return this\n }\n\n clearStrategy(mode?: StrategyMode): this {\n if (mode) {\n this.strategyHandler.delete(mode)\n } else {\n this.strategyHandler.clear()\n }\n return this\n }\n\n private getScheduler(card: CardInput | Card, now: DateInput): IScheduler {\n // Strategy scheduler\n const schedulerStrategy = this.strategyHandler.get(\n StrategyMode.SCHEDULER\n ) as TSchedulerStrategy | undefined\n\n const Scheduler = schedulerStrategy || this.Scheduler\n const instance = new Scheduler(card, now, this, this.strategyHandler)\n\n return instance\n }\n\n repeat(card: CardInput | Card, now: DateInput): IPreview\n repeat<R>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler: (recordLog: IPreview) => R\n ): R\n /**\n * Display the collection of cards and logs for the four scenarios after scheduling the card at the current time.\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * const f = fsrs();\n * const recordLog = f.repeat(card, new Date());\n * ```\n * @example\n * ```typescript\n * interface RevLogUnchecked\n * extends Omit<ReviewLog, \"due\" | \"review\" | \"state\" | \"rating\"> {\n * cid: string;\n * due: Date | number;\n * state: StateType;\n * review: Date | number;\n * rating: RatingType;\n * }\n *\n * interface RepeatRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked;\n * }\n *\n * function repeatAfterHandler(recordLog: RecordLog) {\n * const record: { [key in Grade]: RepeatRecordLog } = {} as {\n * [key in Grade]: RepeatRecordLog;\n * };\n * for (const grade of Grades) {\n * record[grade] = {\n * card: {\n * ...(recordLog[grade].card as Card & { cid: string }),\n * due: recordLog[grade].card.due.getTime(),\n * state: State[recordLog[grade].card.state] as StateType,\n * last_review: recordLog[grade].card.last_review\n * ? recordLog[grade].card.last_review!.getTime()\n * : null,\n * },\n * log: {\n * ...recordLog[grade].log,\n * cid: (recordLog[grade].card as Card & { cid: string }).cid,\n * due: recordLog[grade].log.due.getTime(),\n * review: recordLog[grade].log.review.getTime(),\n * state: State[recordLog[grade].log.state] as StateType,\n * rating: Rating[recordLog[grade].log.rating] as RatingType,\n * },\n * };\n * }\n * return record;\n * }\n * const card: Card = createEmptyCard(new Date(), cardAfterHandler); //see method: createEmptyCard\n * const f = fsrs();\n * const recordLog = f.repeat(card, new Date(), repeatAfterHandler);\n * ```\n */\n repeat<R = IPreview>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler?: (recordLog: IPreview) => R\n ): R {\n const instance = this.getScheduler(card, now)\n const recordLog = instance.preview()\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLog)\n } else {\n return recordLog as R\n }\n }\n\n next(card: CardInput | Card, now: DateInput, grade: Grade): RecordLogItem\n next<R>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler: (recordLog: RecordLogItem) => R\n ): R\n /**\n * Display the collection of cards and logs for the card scheduled at the current time, after applying a specific grade rating.\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param grade Rating of the review (Again, Hard, Good, Easy)\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * const f = fsrs();\n * const recordLogItem = f.next(card, new Date(), Rating.Again);\n * ```\n * @example\n * ```typescript\n * interface RevLogUnchecked\n * extends Omit<ReviewLog, \"due\" | \"review\" | \"state\" | \"rating\"> {\n * cid: string;\n * due: Date | number;\n * state: StateType;\n * review: Date | number;\n * rating: RatingType;\n * }\n *\n * interface NextRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked;\n * }\n *\n function nextAfterHandler(recordLogItem: RecordLogItem) {\n const recordItem = {\n card: {\n ...(recordLogItem.card as Card & { cid: string }),\n due: recordLogItem.card.due.getTime(),\n state: State[recordLogItem.card.state] as StateType,\n last_review: recordLogItem.card.last_review\n ? recordLogItem.card.last_review!.getTime()\n : null,\n },\n log: {\n ...recordLogItem.log,\n cid: (recordLogItem.card as Card & { cid: string }).cid,\n due: recordLogItem.log.due.getTime(),\n review: recordLogItem.log.review.getTime(),\n state: State[recordLogItem.log.state] as StateType,\n rating: Rating[recordLogItem.log.rating] as RatingType,\n },\n };\n return recordItem\n }\n * const card: Card = createEmptyCard(new Date(), cardAfterHandler); //see method: createEmptyCard\n * const f = fsrs();\n * const recordLogItem = f.repeat(card, new Date(), Rating.Again, nextAfterHandler);\n * ```\n */\n next<R = RecordLogItem>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler?: (recordLog: RecordLogItem) => R\n ): R {\n const instance = this.getScheduler(card, now)\n const g = TypeConvert.rating(grade)\n if (g === Rating.Manual) {\n throw new Error('Cannot review a manual rating')\n }\n const recordLogItem = instance.review(g)\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLogItem)\n } else {\n return recordLogItem as R\n }\n }\n\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: true\n ): string\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: false\n ): number\n /**\n * Get the retrievability of the card\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param format default:true , Convert the result to another type. (Optional)\n * @returns The retrievability of the card,if format is true, the result is a string, otherwise it is a number\n */\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format: boolean = true\n ): string | number {\n const processedCard = TypeConvert.card(card)\n now = now ? TypeConvert.time(now) : new Date()\n const t =\n processedCard.state !== State.New\n ? Math.max(date_diff(now, processedCard.last_review as Date, 'days'), 0)\n : 0\n const r =\n processedCard.state !== State.New\n ? this.forgetting_curve(t, +processedCard.stability.toFixed(8))\n : 0\n return format ? `${(r * 100).toFixed(2)}%` : r\n }\n\n rollback(card: CardInput | Card, log: ReviewLogInput): Card\n rollback<R>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler: (prevCard: Card) => R\n ): R\n /**\n *\n * @param card Card to be processed\n * @param log last review log\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now);\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now);\n * const { card, log } = repeatFormAfterHandler[Rating.Hard];\n * const rollbackFromAfterHandler = f.rollback(card, log);\n * ```\n *\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now, cardAfterHandler); //see method: createEmptyCard\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now, repeatAfterHandler); //see method: fsrs.repeat()\n * const { card, log } = repeatFormAfterHandler[Rating.Hard];\n * const rollbackFromAfterHandler = f.rollback(card, log, cardAfterHandler);\n * ```\n */\n rollback<R = Card>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler?: (prevCard: Card) => R\n ): R {\n const processedCard = TypeConvert.card(card)\n const processedLog = TypeConvert.review_log(log)\n if (processedLog.rating === Rating.Manual) {\n throw new Error('Cannot rollback a manual rating')\n }\n let last_due, last_review, last_lapses\n switch (processedLog.state) {\n case State.New:\n last_due = processedLog.due\n last_review = undefined\n last_lapses = 0\n break\n case State.Learning:\n case State.Relearning:\n case State.Review:\n last_due = processedLog.review\n last_review = processedLog.due\n last_lapses =\n processedCard.lapses -\n (processedLog.rating === Rating.Again &&\n processedLog.state === State.Review\n ? 1\n : 0)\n break\n }\n\n const prevCard: Card = {\n ...processedCard,\n due: last_due,\n stability: processedLog.stability,\n difficulty: processedLog.difficulty,\n elapsed_days: processedLog.last_elapsed_days,\n scheduled_days: processedLog.scheduled_days,\n reps: Math.max(0, processedCard.reps - 1),\n lapses: Math.max(0, last_lapses),\n learning_steps: processedLog.learning_steps,\n state: processedLog.state,\n last_review: last_review,\n }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(prevCard)\n } else {\n return prevCard as R\n }\n }\n\n forget(\n card: CardInput | Card,\n now: DateInput,\n reset_count?: boolean\n ): RecordLogItem\n forget<R>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean | undefined,\n afterHandler: (recordLogItem: RecordLogItem) => R\n ): R\n /**\n *\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param reset_count Should the review count information(reps,lapses) be reset. (Optional)\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCard = createEmptyCard(now);\n * const scheduling_cards = f.repeat(emptyCard, now);\n * const { card, log } = scheduling_cards[Rating.Hard];\n * const forgetCard = f.forget(card, new Date(), true);\n * ```\n *\n * @example\n * ```typescript\n * interface RepeatRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked; //see method: fsrs.repeat()\n * }\n *\n * function forgetAfterHandler(recordLogItem: RecordLogItem): RepeatRecordLog {\n * return {\n * card: {\n * ...(recordLogItem.card as Card & { cid: string }),\n * due: recordLogItem.card.due.getTime(),\n * state: State[recordLogItem.card.state] as StateType,\n * last_review: recordLogItem.card.last_review\n * ? recordLogItem.card.last_review!.getTime()\n * : null,\n * },\n * log: {\n * ...recordLogItem.log,\n * cid: (recordLogItem.card as Card & { cid: string }).cid,\n * due: recordLogItem.log.due.getTime(),\n * review: recordLogItem.log.review.getTime(),\n * state: State[recordLogItem.log.state] as StateType,\n * rating: Rating[recordLogItem.log.rating] as RatingType,\n * },\n * };\n * }\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now, cardAfterHandler); //see method: createEmptyCard\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now, repeatAfterHandler); //see method: fsrs.repeat()\n * const { card } = repeatFormAfterHandler[Rating.Hard];\n * const forgetFromAfterHandler = f.forget(card, date_scheduler(now, 1, true), false, forgetAfterHandler);\n * ```\n */\n forget<R = RecordLogItem>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean = false,\n afterHandler?: (recordLogItem: RecordLogItem) => R\n ): R {\n const processedCard = TypeConvert.card(card)\n now = TypeConvert.time(now)\n const scheduled_days =\n processedCard.state === State.New\n ? 0\n : date_diff(now, processedCard.due as Date, 'days')\n const forget_log: ReviewLog = {\n rating: Rating.Manual,\n state: processedCard.state,\n due: processedCard.due,\n stability: processedCard.stability,\n difficulty: processedCard.difficulty,\n elapsed_days: 0,\n last_elapsed_days: processedCard.elapsed_days,\n scheduled_days: scheduled_days,\n learning_steps: processedCard.learning_steps,\n review: now,\n }\n const forget_card: Card = {\n ...processedCard,\n due: now,\n stability: 0,\n difficulty: 0,\n elapsed_days: 0,\n scheduled_days: 0,\n reps: reset_count ? 0 : processedCard.reps,\n lapses: reset_count ? 0 : processedCard.lapses,\n learning_steps: 0,\n state: State.New,\n last_review: processedCard.last_review,\n }\n const recordLogItem: RecordLogItem = { card: forget_card, log: forget_log }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLogItem)\n } else {\n return recordLogItem as R\n }\n }\n\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews: FSRSHistory[] | undefined,\n options: RequireOnly<RescheduleOptions<T>, 'recordLogHandler'>\n ): IReschedule<T>\n reschedule(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: Partial<RescheduleOptions<RecordLogItem>>\n ): IReschedule<RecordLogItem>\n /**\n * Reschedules the current card and returns the rescheduled collections and reschedule item.\n *\n * @template T - The type of the record log item.\n * @param {CardInput | Card} current_card - The current card to be rescheduled.\n * @param {Array<FSRSHistory>} reviews - The array of FSRSHistory objects representing the reviews.\n * @param {Partial<RescheduleOptions<T>>} options - The optional reschedule options.\n * @returns {IReschedule<T>} - The rescheduled collections and reschedule item.\n *\n * @example\n * ```typescript\n * const f = fsrs()\n * const grades: Grade[] = [Rating.Good, Rating.Good, Rating.Good, Rating.Good]\n * const reviews_at = [\n * new Date(2024, 8, 13),\n * new Date(2024, 8, 13),\n * new Date(2024, 8, 17),\n * new Date(2024, 8, 28),\n * ]\n *\n * const reviews: FSRSHistory[] = []\n * for (let i = 0; i < grades.length; i++) {\n * reviews.push({\n * rating: grades[i],\n * review: reviews_at[i],\n * })\n * }\n *\n * const results_short = scheduler.reschedule(\n * createEmptyCard(),\n * reviews,\n * {\n * skipManual: false,\n * }\n * )\n * console.log(results_short)\n * ```\n */\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews: FSRSHistory[] = [],\n options: Partial<RescheduleOptions<T>> = {}\n ): IReschedule<T> {\n const {\n recordLogHandler,\n reviewsOrderBy,\n skipManual: skipManual = true,\n now: now = new Date(),\n update_memory_state: updateMemoryState = false,\n } = options\n if (reviewsOrderBy && typeof reviewsOrderBy === 'function') {\n reviews.sort(reviewsOrderBy)\n }\n if (skipManual) {\n reviews = reviews.filter((review) => review.rating !== Rating.Manual)\n }\n const rescheduleSvc = new Reschedule(this)\n\n const collections = rescheduleSvc.reschedule(\n options.first_card || createEmptyCard(),\n reviews\n )\n const len = collections.length\n const cur_card = TypeConvert.card(current_card)\n const manual_item = rescheduleSvc.calculateManualRecord(\n cur_card,\n now,\n len ? collections[len - 1] : undefined,\n updateMemoryState\n )\n\n if (recordLogHandler && typeof recordLogHandler === 'function') {\n return {\n collections: collections.map(recordLogHandler),\n reschedule_item: manual_item ? recordLogHandler(manual_item) : null,\n }\n }\n return {\n collections,\n reschedule_item: manual_item,\n } as IReschedule<T>\n }\n}\n\n/**\n * Create a new instance of TS-FSRS\n * @param params FSRSParameters\n * @example\n * ```typescript\n * const f = fsrs();\n * ```\n * @example\n * ```typescript\n * const params: FSRSParameters = generatorParameters({ maximum_interval: 1000 });\n * const f = fsrs(params);\n * ```\n * @example\n * ```typescript\n * const f = fsrs({ maximum_interval: 1000 });\n * ```\n */\nexport const fsrs = (params?: Partial<FSRSParameters>) => {\n return new FSRS(params || {})\n}\n"],"names":["State","t","Rating","e","TypeConvert","card","value","firstLetter","restOfString","ret","timestamp","log","isDay","date_scheduler","pre","unit","date_diff","formatDate","last_review","timeUnit","show_diff_message","now","diff","dateInput","date","year","month","day","hours","minutes","seconds","padZero","num","TIMEUNIT","TIMEUNITFORMAT","due","i","fixDate","fixState","fixRating","Grades","FUZZ_RANGES","get_fuzz_range","interval","elapsed_days","maximum_interval","delta","range","min_ivl","max_ivl","clamp","min","max","dateDiffInDays","last","cur","utc1","utc2","default_request_retention","default_maximum_interval","default_enable_fuzz","default_enable_short_term","default_learning_steps","default_relearning_steps","FSRSVersion","version","S_MIN","S_MAX","INIT_S_MAX","FSRS5_DEFAULT_DECAY","FSRS6_DEFAULT_DECAY","default_w","W17_W18_Ceiling","CLAMP_PARAMETERS","w17_w18_ceiling","clipParameters","parameters","numRelearningSteps","index","checkParameters","param","migrateParameters","w","generatorParameters","props","learning_steps","relearning_steps","createEmptyCard","afterHandler","emptyCard","Alea","seed","mash","Mash","state","n","data","h","alea","xg","prng","computeDecayFactor","decayOrParams","decay","factor","forgetting_curve","stability","FSRSAlgorithm","params","request_retention","_this","target","prop","_params","key","paramKey","g","ivl","fuzz_factor","s","newInterval","delta_d","old_d","d","next_d","init","current","r","hard_penalty","easy_bound","sinc","maskedSinc","memory_state","s_after_success","s_after_fail","s_after_short_term","new_s","w_17","w_18","next_s_min","DefaultInitSeedStrategy","time","reps","mul","GenSeedStrategyWithCardId","card_id_field","card_id","ConvertStepUnitToMinutes","step","BasicLearningStepsStrategy","cur_step","steps_length","firstStep","toMinutes","getAgainInterval","getHardInterval","nextStep","getStepInfo","getGoodMinutes","result","step_info","next_info","nextMin","StrategyMode","AbstractScheduler","algorithm","strategies","grade","seed_strategy","custom_strategy","item","rating","BasicScheduler","learningStepStrategy","steps_strategy","scheduled_minutes","next_steps","nextCard","to_state","exist","next","difficulty","retrievability","next_again","next_hard","next_good","next_easy","item_again","item_hard","item_good","item_easy","nextSMin","hard_interval","good_interval","easy_interval","LongTermScheduler","again_interval","Reschedule","fsrs","reviewed","next_card","scheduled_days","current_card","reviews","collections","cur_card","review","record_log_item","update_memory","reschedule_card","FSRS","enable_short_term","mode","handler","Scheduler","recordLog","instance","recordLogItem","format","processedCard","processedLog","last_due","last_lapses","prevCard","reset_count","forget_log","options","recordLogHandler","reviewsOrderBy","skipManual","updateMemoryState","rescheduleSvc","len","manual_item"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/fsrs/models.ts","../src/fsrs/convert.ts","../src/fsrs/help.ts","../src/fsrs/strategies/learning_steps.ts","../src/fsrs/strategies/seed.ts","../src/fsrs/strategies/types.ts","../src/fsrs/abstract_scheduler.ts","../src/fsrs/alea.ts","../src/fsrs/constant.ts","../src/fsrs/default.ts","../src/fsrs/algorithm.ts","../src/fsrs/impl/basic_scheduler.ts","../src/fsrs/impl/long_term_scheduler.ts","../src/fsrs/reschedule.ts","../src/fsrs/fsrs.ts"],"sourcesContent":["export type StateType = 'New' | 'Learning' | 'Review' | 'Relearning'\n\nexport enum State {\n New = 0,\n Learning = 1,\n Review = 2,\n Relearning = 3,\n}\n\nexport type RatingType = 'Manual' | 'Again' | 'Hard' | 'Good' | 'Easy'\n\nexport enum Rating {\n Manual = 0,\n Again = 1,\n Hard = 2,\n Good = 3,\n Easy = 4,\n}\n\nexport type GradeType = Exclude<RatingType, 'Manual'>\nexport type Grade = Exclude<Rating, Rating.Manual>\n\nexport interface ReviewLog {\n rating: Rating // Rating of the review (Again, Hard, Good, Easy)\n state: State // State of the review (New, Learning, Review, Relearning)\n due: Date // Date of the last scheduling\n stability: number // Memory stability during the review\n difficulty: number // Difficulty of the card during the review\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n elapsed_days: number // Number of days elapsed since the last review\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n last_elapsed_days: number // Number of days between the last two reviews\n scheduled_days: number // Number of days until the next review\n learning_steps: number // Keeps track of the current step during the (re)learning stages\n review: Date // Date of the review\n}\n\nexport type RecordLogItem = {\n card: Card\n log: ReviewLog\n}\nexport type RecordLog = {\n [key in Grade]: RecordLogItem\n}\n\nexport interface Card {\n due: Date // Due date\n stability: number // Stability\n difficulty: number // Difficulty level\n /**\n * @deprecated This field will be removed in version 6.0.0\n */\n elapsed_days: number // Number of days elapsed\n scheduled_days: number // Number of days scheduled\n learning_steps: number // Keeps track of the current step during the (re)learning stages\n reps: number // Repetition count\n lapses: number // Number of lapses or mistakes\n state: State // Card's state (New, Learning, Review, Relearning)\n last_review?: Date // Date of the last review (optional)\n}\n\nexport interface CardInput extends Omit<Card, 'state' | 'due' | 'last_review'> {\n state: StateType | State // Card's state (New, Learning, Review, Relearning)\n due: DateInput // Due date\n last_review?: DateInput | null // Date of the last review (optional)\n}\n\nexport type DateInput = Date | number | string\nexport type TimeUnit = 'm' | 'h' | 'd'\nexport type StepUnit = `${number}${TimeUnit}`\n/**\n * (re)Learning steps:\n * [1m, 10m]\n * step1:again=1m hard=6m good=10m\n * step2(good): again=1m hard=10m\n *\n * [5m]\n * step1:again=5m hard=8m\n * step2(good): again=5m\n * step2(hard): again=5m hard=7.5m\n *\n * []\n * step: Managed by FSRS\n *\n */\nexport type Steps = StepUnit[] | readonly StepUnit[]\n\nexport interface ReviewLogInput\n extends Omit<ReviewLog, 'rating' | 'state' | 'due' | 'review'> {\n rating: RatingType | Rating // Rating of the review (Again, Hard, Good, Easy)\n state: StateType | State // Card's state (New, Learning, Review, Relearning)\n due: DateInput // Due date\n review: DateInput // Date of the last review\n}\n\nexport interface FSRSParameters {\n request_retention: number\n maximum_interval: number\n w: number[] | readonly number[]\n enable_fuzz: boolean\n /**\n * When enable_short_term = false, the (re)learning steps are not applied.\n */\n enable_short_term: boolean\n learning_steps: Steps\n relearning_steps: Steps\n}\n\nexport interface FSRSReview {\n /**\n * 0-4: Manual, Again, Hard, Good, Easy\n * = revlog.rating\n */\n rating: Rating\n /**\n * The number of days that passed\n * = revlog.elapsed_days\n * = round(revlog[-1].review - revlog[-2].review)\n */\n delta_t: number\n}\n\nexport type FSRSHistory = Partial<\n Omit<ReviewLog, 'rating' | 'review' | 'elapsed_days'>\n> &\n (\n | {\n rating: Grade\n review: DateInput | Date\n }\n | {\n rating: Rating.Manual\n due: DateInput | Date\n state: State\n review: DateInput | Date\n }\n )\n\nexport interface FSRSState {\n stability: number\n difficulty: number\n}\n","import {\n type Card,\n type CardInput,\n Rating,\n type ReviewLog,\n type ReviewLogInput,\n State,\n} from './models'\n\nexport class TypeConvert {\n static card<T extends Card | CardInput>(card: T): Card {\n return {\n ...card,\n state: TypeConvert.state(card.state),\n due: TypeConvert.time(card.due),\n last_review: card.last_review\n ? TypeConvert.time(card.last_review)\n : undefined,\n } as Card\n }\n static rating(value: unknown): Rating {\n if (typeof value === 'string') {\n const firstLetter = value.charAt(0).toUpperCase()\n const restOfString = value.slice(1).toLowerCase()\n const ret = Rating[`${firstLetter}${restOfString}` as keyof typeof Rating]\n if (ret === undefined) {\n throw new Error(`Invalid rating:[${value}]`)\n }\n return ret\n } else if (typeof value === 'number') {\n return value as Rating\n }\n throw new Error(`Invalid rating:[${value}]`)\n }\n static state(value: unknown): State {\n if (typeof value === 'string') {\n const firstLetter = value.charAt(0).toUpperCase()\n const restOfString = value.slice(1).toLowerCase()\n const ret = State[`${firstLetter}${restOfString}` as keyof typeof State]\n if (ret === undefined) {\n throw new Error(`Invalid state:[${value}]`)\n }\n return ret\n } else if (typeof value === 'number') {\n return value as State\n }\n throw new Error(`Invalid state:[${value}]`)\n }\n static time(value: unknown): Date {\n if (typeof value === 'object' && value instanceof Date) {\n return value\n } else if (typeof value === 'string') {\n const timestamp = Date.parse(value)\n if (!Number.isNaN(timestamp)) {\n return new Date(timestamp)\n } else {\n throw new Error(`Invalid date:[${value}]`)\n }\n } else if (typeof value === 'number') {\n return new Date(value)\n }\n throw new Error(`Invalid date:[${value}]`)\n }\n static review_log(log: ReviewLogInput | ReviewLog): ReviewLog {\n return {\n ...log,\n due: TypeConvert.time(log.due),\n rating: TypeConvert.rating(log.rating),\n state: TypeConvert.state(log.state),\n review: TypeConvert.time(log.review),\n } satisfies ReviewLog\n }\n}\n","import { TypeConvert } from './convert'\nimport type { DateInput, Grade } from './models'\nimport { Rating, type State } from './models'\nimport type { int, unit } from './types'\n\ndeclare global {\n export interface Date {\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n scheduler(t: int, isDay?: boolean): Date\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n diff(pre: Date, unit: unit): int\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n format(): string\n /**\n * @deprecated This method will be removed in version 6.0.0.\n *\n */\n dueFormat(last_review: Date, unit?: boolean, timeUnit?: string[]): string\n }\n}\n\n/* istanbul ignore next */\nDate.prototype.scheduler = function (t: int, isDay?: boolean): Date {\n return date_scheduler(this, t, isDay)\n}\n\n/**\n * 当前时间与之前的时间差值\n * @param pre 比当前时间还要之前\n * @param unit 单位: days | minutes\n */\n/* istanbul ignore next */\nDate.prototype.diff = function (pre: Date, unit: unit): int {\n return date_diff(this, pre, unit) as int\n}\n\n/* istanbul ignore next */\nDate.prototype.format = function (): string {\n return formatDate(this)\n}\n\n/* istanbul ignore next */\nDate.prototype.dueFormat = function (\n last_review: Date,\n unit?: boolean,\n timeUnit?: string[]\n) {\n return show_diff_message(this, last_review, unit, timeUnit)\n}\n\n/**\n * 计算日期和时间的偏移,并返回一个新的日期对象。\n * @param now 当前日期和时间\n * @param t 时间偏移量,当 isDay 为 true 时表示天数,为 false 时表示分钟\n * @param isDay (可选)是否按天数单位进行偏移,默认为 false,表示按分钟单位计算偏移\n * @returns 偏移后的日期和时间对象\n */\nexport function date_scheduler(\n now: DateInput,\n t: number,\n isDay?: boolean\n): Date {\n return new Date(\n isDay\n ? TypeConvert.time(now).getTime() + t * 24 * 60 * 60 * 1000\n : TypeConvert.time(now).getTime() + t * 60 * 1000\n )\n}\n\nexport function date_diff(now: DateInput, pre: DateInput, unit: unit): number {\n if (!now || !pre) {\n throw new Error('Invalid date')\n }\n const diff = TypeConvert.time(now).getTime() - TypeConvert.time(pre).getTime()\n let r = 0\n switch (unit) {\n case 'days':\n r = Math.floor(diff / (24 * 60 * 60 * 1000))\n break\n case 'minutes':\n r = Math.floor(diff / (60 * 1000))\n break\n }\n return r\n}\n\nexport function formatDate(dateInput: DateInput): string {\n const date = TypeConvert.time(dateInput)\n const year: number = date.getFullYear()\n const month: number = date.getMonth() + 1\n const day: number = date.getDate()\n const hours: number = date.getHours()\n const minutes: number = date.getMinutes()\n const seconds: number = date.getSeconds()\n\n return `${year}-${padZero(month)}-${padZero(day)} ${padZero(hours)}:${padZero(\n minutes\n )}:${padZero(seconds)}`\n}\n\nfunction padZero(num: number): string {\n return num < 10 ? `0${num}` : `${num}`\n}\n\nconst TIMEUNIT = [60, 60, 24, 31, 12]\nconst TIMEUNITFORMAT = ['second', 'min', 'hour', 'day', 'month', 'year']\n\nexport function show_diff_message(\n due: DateInput,\n last_review: DateInput,\n unit?: boolean,\n timeUnit: string[] = TIMEUNITFORMAT\n): string {\n due = TypeConvert.time(due)\n last_review = TypeConvert.time(last_review)\n if (timeUnit.length !== TIMEUNITFORMAT.length) {\n timeUnit = TIMEUNITFORMAT\n }\n let diff = due.getTime() - last_review.getTime()\n let i = 0\n diff /= 1000\n for (i = 0; i < TIMEUNIT.length; i++) {\n if (diff < TIMEUNIT[i]) {\n break\n } else {\n diff /= TIMEUNIT[i]\n }\n }\n return `${Math.floor(diff)}${unit ? timeUnit[i] : ''}`\n}\n\n/* istanbul ignore next */\n/**\n *\n * @deprecated Use TypeConvert.time instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixDate(value: unknown) {\n return TypeConvert.time(value)\n}\n\n/* istanbul ignore next */\n/**\n * @deprecated Use TypeConvert.state instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixState(value: unknown): State {\n return TypeConvert.state(value)\n}\n\n/* istanbul ignore next */\n/**\n * @deprecated Use TypeConvert.rating instead\n * @deprecated This function will be removed in version 6.0.0.\n */\nexport function fixRating(value: unknown): Rating {\n return TypeConvert.rating(value)\n}\n\nexport const Grades: Readonly<Grade[]> = Object.freeze([\n Rating.Again,\n Rating.Hard,\n Rating.Good,\n Rating.Easy,\n])\n\nconst FUZZ_RANGES = [\n {\n start: 2.5,\n end: 7.0,\n factor: 0.15,\n },\n {\n start: 7.0,\n end: 20.0,\n factor: 0.1,\n },\n {\n start: 20.0,\n end: Infinity,\n factor: 0.05,\n },\n] as const\n\nexport function get_fuzz_range(\n interval: number,\n elapsed_days: number,\n maximum_interval: number\n) {\n let delta = 1.0\n for (const range of FUZZ_RANGES) {\n delta +=\n range.factor * Math.max(Math.min(interval, range.end) - range.start, 0.0)\n }\n interval = Math.min(interval, maximum_interval)\n let min_ivl = Math.max(2, Math.round(interval - delta))\n const max_ivl = Math.min(Math.round(interval + delta), maximum_interval)\n if (interval > elapsed_days) {\n min_ivl = Math.max(min_ivl, elapsed_days + 1)\n }\n min_ivl = Math.min(min_ivl, max_ivl)\n return { min_ivl, max_ivl }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n\nexport function dateDiffInDays(last: Date, cur: Date) {\n // Discard the time and time-zone information.\n const utc1 = Date.UTC(\n last.getUTCFullYear(),\n last.getUTCMonth(),\n last.getUTCDate()\n )\n const utc2 = Date.UTC(\n cur.getUTCFullYear(),\n cur.getUTCMonth(),\n cur.getUTCDate()\n )\n\n return Math.floor((utc2 - utc1) / 86400000 /** 1000 * 60 * 60 * 24*/)\n}\n","import {\n type FSRSParameters,\n Rating,\n State,\n type StepUnit,\n type TimeUnit,\n} from '../models'\nimport type { TLearningStepsStrategy } from './types'\n\nexport const ConvertStepUnitToMinutes = (step: StepUnit): number => {\n const unit = step.slice(-1) as TimeUnit\n const value = parseInt(step.slice(0, -1), 10)\n if (Number.isNaN(value) || !Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid step value: ${step}`)\n }\n switch (unit) {\n case 'm':\n return value\n case 'h':\n return value * 60\n case 'd':\n return value * 1440\n default:\n throw new Error(`Invalid step unit: ${step}, expected m/h/d`)\n }\n}\n\nexport const BasicLearningStepsStrategy: TLearningStepsStrategy = (\n params: FSRSParameters,\n state: State,\n cur_step: number\n) => {\n const learning_steps =\n state === State.Relearning || state === State.Review\n ? params.relearning_steps\n : params.learning_steps\n const steps_length = learning_steps.length\n // steps_length === 0 ,return empty object\n if (steps_length === 0 || cur_step >= steps_length) return {}\n\n // steps_length > 0\n const firstStep = learning_steps[0]\n\n const toMinutes = ConvertStepUnitToMinutes\n\n const getAgainInterval = (): number => {\n return toMinutes(firstStep)\n }\n\n const getHardInterval = (): number => {\n // steps_length > 0,return firstStep*1.5\n if (steps_length === 1) return Math.round(toMinutes(firstStep) * 1.5)\n // steps_length > 1,return (firstStep+nextStep)/2\n const nextStep = learning_steps[1]\n return Math.round((toMinutes(firstStep) + toMinutes(nextStep)) / 2)\n }\n\n const getStepInfo = (index: number) => {\n if (index < 0 || index >= steps_length) {\n return null\n } else {\n return learning_steps[index]\n }\n }\n\n const getGoodMinutes = (step: StepUnit): number | null => {\n return toMinutes(step)\n }\n\n const result: ReturnType<TLearningStepsStrategy> = {}\n const step_info = getStepInfo(Math.max(0, cur_step))\n // review -> again\n // new, learning, relearning -> again,hard,good(if next step exists)\n if (state === State.Review) {\n // review\n result[Rating.Again] = {\n scheduled_minutes: toMinutes(step_info!),\n next_step: 0,\n }\n return result\n } else {\n // new,learning, relearning\n result[Rating.Again] = {\n scheduled_minutes: getAgainInterval(),\n next_step: 0,\n }\n\n result[Rating.Hard] = {\n scheduled_minutes: getHardInterval(),\n next_step: cur_step,\n }\n const next_info = getStepInfo(cur_step + 1)\n if (next_info) {\n const nextMin = getGoodMinutes(next_info)\n\n if (nextMin) {\n result[Rating.Good] = {\n scheduled_minutes: Math.round(nextMin),\n next_step: cur_step + 1,\n }\n }\n }\n }\n return result\n}\n","import type { AbstractScheduler } from '../abstract_scheduler'\nimport type { TSeedStrategy } from './types'\n\nexport function DefaultInitSeedStrategy(this: AbstractScheduler): string {\n const time = this.review_time.getTime()\n const reps = this.current.reps\n const mul = this.current.difficulty * this.current.stability\n return `${time}_${reps}_${mul}`\n}\n\n/**\n * Generates a seed strategy function for card IDs.\n *\n * @param card_id_field - The field name of the card ID in the current object.\n * @returns A function that generates a seed based on the card ID and repetitions.\n *\n * @remarks\n * The returned function uses the `card_id_field` to retrieve the card ID from the current object.\n * It then adds the number of repetitions (`reps`) to the card ID to generate the seed.\n *\n * @example\n * ```typescript\n * const seedStrategy = GenCardIdSeedStrategy('card_id');\n * const f = fsrs().useStrategy(StrategyMode.SEED, seedStrategy)\n * const card = createEmptyCard<Card & { card_id: number }>()\n * card.card_id = 555\n * const record = f.repeat(card, new Date())\n * ```\n */\nexport function GenSeedStrategyWithCardId(\n card_id_field: string | number\n): TSeedStrategy {\n return function (this: AbstractScheduler): string {\n // https://github.com/open-spaced-repetition/ts-fsrs/issues/131#issuecomment-2408426225\n const card_id = Reflect.get(this.current, card_id_field) ?? 0\n const reps = this.current.reps\n // ex1\n // card_id:string + reps:number = 'e2ecb1f7-8d15-420b-bec4-c7212ad2e5dc' + 4\n // = 'e2ecb1f7-8d15-420b-bec4-c7212ad2e5dc4'\n\n // ex2\n // card_id:number + reps:number = 1732452519198 + 4\n // = '17324525191984'\n return String(card_id + reps || 0)\n }\n}\n","import type { AbstractScheduler } from '../abstract_scheduler'\nimport type { FSRSAlgorithm } from '../algorithm'\nimport type {\n Card,\n CardInput,\n DateInput,\n FSRSParameters,\n Grade,\n State,\n} from '../models'\nimport type { IScheduler } from '../types'\n\nexport enum StrategyMode {\n SCHEDULER = 'Scheduler',\n LEARNING_STEPS = 'LearningSteps',\n SEED = 'Seed',\n}\n\nexport type TSeedStrategy = (this: AbstractScheduler) => string\nexport type TSchedulerStrategy<T extends CardInput | Card = CardInput | Card> =\n new (\n card: T,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies: Map<StrategyMode, TStrategyHandler>\n ) => IScheduler\n\n/**\n * When enable_short_term = false, the learning steps strategy will not take effect.\n */\nexport type TLearningStepsStrategy = (\n params: FSRSParameters,\n state: State,\n cur_step: number\n) => {\n [K in Grade]?: { scheduled_minutes: number; next_step: number }\n}\n\ntype StrategyMap = {\n [StrategyMode.SCHEDULER]: TSchedulerStrategy\n [StrategyMode.SEED]: TSeedStrategy\n [StrategyMode.LEARNING_STEPS]: TLearningStepsStrategy\n}\n\nexport type TStrategyHandler<E = StrategyMode> = E extends StrategyMode\n ? StrategyMap[E]\n : never\n","import type { FSRSAlgorithm } from './algorithm'\nimport { TypeConvert } from './convert'\nimport { dateDiffInDays, Grades } from './help'\nimport {\n type Card,\n type CardInput,\n type DateInput,\n type Grade,\n Rating,\n type RecordLogItem,\n type ReviewLog,\n State,\n} from './models'\nimport { DefaultInitSeedStrategy } from './strategies'\nimport {\n StrategyMode,\n type TSeedStrategy,\n type TStrategyHandler,\n} from './strategies/types'\nimport type { IPreview, IScheduler } from './types'\n\nexport abstract class AbstractScheduler implements IScheduler {\n protected last: Card\n protected current: Card\n protected review_time: Date\n protected next: Map<Grade, RecordLogItem> = new Map()\n protected algorithm: FSRSAlgorithm\n protected strategies: Map<StrategyMode, TStrategyHandler> | undefined\n protected elapsed_days: number = 0 // init\n\n constructor(\n card: CardInput | Card,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies?: Map<StrategyMode, TStrategyHandler>\n ) {\n this.algorithm = algorithm\n this.last = TypeConvert.card(card)\n this.current = TypeConvert.card(card)\n this.review_time = TypeConvert.time(now)\n this.strategies = strategies\n this.init()\n }\n\n protected checkGrade(grade: Grade): void {\n if (!Number.isFinite(grade) || grade < 0 || grade > 4) {\n throw new Error(`Invalid grade \"${grade}\",expected 1-4`)\n }\n }\n\n private init() {\n const { state, last_review } = this.current\n let interval = 0 // card.state === State.New => 0\n if (state !== State.New && last_review) {\n interval = dateDiffInDays(last_review, this.review_time)\n }\n this.current.last_review = this.review_time\n this.elapsed_days = interval\n // pending removal in v6.0.0\n this.current.elapsed_days = interval\n this.current.reps += 1\n\n // init seed strategy\n let seed_strategy = DefaultInitSeedStrategy\n if (this.strategies) {\n const custom_strategy = this.strategies.get(StrategyMode.SEED)\n if (custom_strategy) {\n seed_strategy = custom_strategy as TSeedStrategy\n }\n }\n this.algorithm.seed = (<TSeedStrategy>seed_strategy).call(this)\n }\n\n public preview(): IPreview {\n return {\n [Rating.Again]: this.review(Rating.Again),\n [Rating.Hard]: this.review(Rating.Hard),\n [Rating.Good]: this.review(Rating.Good),\n [Rating.Easy]: this.review(Rating.Easy),\n [Symbol.iterator]: this.previewIterator.bind(this),\n } satisfies IPreview\n }\n\n private *previewIterator(): IterableIterator<RecordLogItem> {\n for (const grade of Grades) {\n yield this.review(grade)\n }\n }\n\n public review(grade: Grade): RecordLogItem {\n const { state } = this.last\n let item: RecordLogItem | undefined\n this.checkGrade(grade)\n switch (state) {\n case State.New:\n item = this.newState(grade)\n break\n case State.Learning:\n case State.Relearning:\n item = this.learningState(grade)\n break\n case State.Review:\n item = this.reviewState(grade)\n break\n }\n return item\n }\n\n protected abstract newState(grade: Grade): RecordLogItem\n\n protected abstract learningState(grade: Grade): RecordLogItem\n\n protected abstract reviewState(grade: Grade): RecordLogItem\n\n protected buildLog(rating: Grade): ReviewLog {\n const { last_review, due, elapsed_days } = this.last\n\n return {\n rating: rating,\n state: this.current.state,\n due: last_review || due,\n stability: this.current.stability,\n difficulty: this.current.difficulty,\n elapsed_days: this.elapsed_days,\n last_elapsed_days: elapsed_days,\n scheduled_days: this.current.scheduled_days,\n learning_steps: this.current.learning_steps,\n review: this.review_time,\n } satisfies ReviewLog\n }\n}\n","// https://github.com/davidbau/seedrandom/blob/released/lib/alea.js\n// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010\n// http://baagoe.com/en/RandomMusings/javascript/\n// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror\n// Original work is under MIT license -\n\n// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\ntype State = {\n c: number\n s0: number\n s1: number\n s2: number\n}\n\nclass Alea {\n private c: number\n private s0: number\n private s1: number\n private s2: number\n\n constructor(seed?: number | string) {\n const mash = Mash()\n this.c = 1\n this.s0 = mash(' ')\n this.s1 = mash(' ')\n this.s2 = mash(' ')\n if (seed == null) seed = Date.now()\n this.s0 -= mash(seed)\n if (this.s0 < 0) this.s0 += 1\n this.s1 -= mash(seed)\n if (this.s1 < 0) this.s1 += 1\n this.s2 -= mash(seed)\n if (this.s2 < 0) this.s2 += 1\n }\n\n next(): number {\n const t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10 // 2^-32\n this.s0 = this.s1\n this.s1 = this.s2\n this.c = t | 0\n this.s2 = t - this.c\n return this.s2\n }\n\n set state(state: State) {\n this.c = state.c\n this.s0 = state.s0\n this.s1 = state.s1\n this.s2 = state.s2\n }\n\n get state(): State {\n return {\n c: this.c,\n s0: this.s0,\n s1: this.s1,\n s2: this.s2,\n }\n }\n}\n\nfunction Mash() {\n let n = 0xefc8249d\n return function mash(data: string | number): number {\n data = String(data)\n for (let i = 0; i < data.length; i++) {\n n += data.charCodeAt(i)\n let h = 0.02519603282416938 * n\n n = h >>> 0\n h -= n\n h *= n\n n = h >>> 0\n h -= n\n n += h * 0x100000000 // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10 // 2^-32\n }\n}\n\nfunction alea(seed?: number | string) {\n const xg = new Alea(seed)\n const prng = () => xg.next()\n\n prng.int32 = () => (xg.next() * 0x100000000) | 0\n prng.double = () =>\n prng() + ((prng() * 0x200000) | 0) * 1.1102230246251565e-16 // 2^-53\n prng.state = () => xg.state\n prng.importState = (state: State) => {\n xg.state = state\n return prng\n }\n return prng\n}\n\nexport { alea }\n","import { version } from '../../package.json'\nimport type { StepUnit } from './models'\n\nexport const default_request_retention = 0.9\nexport const default_maximum_interval = 36500\nexport const default_enable_fuzz = false\nexport const default_enable_short_term = true\nexport const default_learning_steps: readonly StepUnit[] = Object.freeze([\n '1m',\n '10m',\n]) // New->Learning,Learning->Learning\n\nexport const default_relearning_steps: readonly StepUnit[] = Object.freeze([\n '10m',\n]) // Relearning->Relearning\n\nexport const FSRSVersion: string = `v${version} using FSRS-6.0`\n\nexport const S_MIN = 0.001\nexport const S_MAX = 36500.0\nexport const INIT_S_MAX = 100.0\nexport const FSRS5_DEFAULT_DECAY = 0.5\nexport const FSRS6_DEFAULT_DECAY = 0.1542\nexport const default_w = Object.freeze([\n 0.212,\n 1.2931,\n 2.3065,\n 8.2956,\n 6.4133,\n 0.8334,\n 3.0194,\n 0.001,\n 1.8722,\n 0.1666,\n 0.796,\n 1.4835,\n 0.0614,\n 0.2629,\n 1.6483,\n 0.6014,\n 1.8729,\n 0.5425,\n 0.0912,\n 0.0658,\n FSRS6_DEFAULT_DECAY,\n]) satisfies readonly number[]\n\nexport const W17_W18_Ceiling = 2.0\nexport const CLAMP_PARAMETERS = (\n w17_w18_ceiling: number,\n enable_short_term: boolean = default_enable_short_term\n) => [\n [S_MIN, INIT_S_MAX] /** initial stability (Again) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Hard) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Good) */,\n [S_MIN, INIT_S_MAX] /** initial stability (Easy) */,\n [1.0, 10.0] /** initial difficulty (Good) */,\n [0.001, 4.0] /** initial difficulty (multiplier) */,\n [0.001, 4.0] /** difficulty (multiplier) */,\n [0.001, 0.75] /** difficulty (multiplier) */,\n [0.0, 4.5] /** stability (exponent) */,\n [0.0, 0.8] /** stability (negative power) */,\n [0.001, 3.5] /** stability (exponent) */,\n [0.001, 5.0] /** fail stability (multiplier) */,\n [0.001, 0.25] /** fail stability (negative power) */,\n [0.001, 0.9] /** fail stability (power) */,\n [0.0, 4.0] /** fail stability (exponent) */,\n [0.0, 1.0] /** stability (multiplier for Hard) */,\n [1.0, 6.0] /** stability (multiplier for Easy) */,\n [0.0, w17_w18_ceiling] /** short-term stability (exponent) */,\n [0.0, w17_w18_ceiling] /** short-term stability (exponent) */,\n [\n enable_short_term ? 0.01 : 0.0,\n 0.8,\n ] /** short-term last-stability (exponent) */,\n [0.1, 0.8] /** decay */,\n]\n","import {\n CLAMP_PARAMETERS,\n default_enable_fuzz,\n default_enable_short_term,\n default_learning_steps,\n default_maximum_interval,\n default_relearning_steps,\n default_request_retention,\n default_w,\n FSRS5_DEFAULT_DECAY,\n W17_W18_Ceiling,\n} from './constant'\nimport { TypeConvert } from './convert'\nimport { clamp } from './help'\nimport { type Card, type DateInput, type FSRSParameters, State } from './models'\n\nexport const clipParameters = (\n parameters: number[],\n numRelearningSteps: number,\n enableShortTerm: boolean = default_enable_short_term\n) => {\n let w17_w18_ceiling = W17_W18_Ceiling\n if (Math.max(0, numRelearningSteps) > 1) {\n // PLS = w11 * D ^ -w12 * [(S + 1) ^ w13 - 1] * e ^ (w14 * (1 - R))\n // PLS * e ^ (num_relearning_steps * w17 * w18) should be <= S\n // Given D = 1, R = 0.7, S = 1, PLS is equal to w11 * (2 ^ w13 - 1) * e ^ (w14 * 0.3)\n // So num_relearning_steps * w17 * w18 + ln(w11) + ln(2 ^ w13 - 1) + w14 * 0.3 should be <= ln(1)\n // => num_relearning_steps * w17 * w18 <= - ln(w11) - ln(2 ^ w13 - 1) - w14 * 0.3\n // => w17 * w18 <= -[ln(w11) + ln(2 ^ w13 - 1) + w14 * 0.3] / num_relearning_steps\n const value =\n -(\n Math.log(parameters[11]) +\n Math.log(Math.pow(2.0, parameters[13]) - 1.0) +\n parameters[14] * 0.3\n ) / numRelearningSteps\n\n w17_w18_ceiling = clamp(+value.toFixed(8), 0.01, 2.0)\n }\n const clip = CLAMP_PARAMETERS(w17_w18_ceiling, enableShortTerm).slice(\n 0,\n parameters.length\n )\n return clip.map(([min, max], index) =>\n clamp(parameters[index] || 0, min, max)\n )\n}\n\n/**\n * @returns The input if the parameters are valid, throws if they are invalid\n * @example\n * try {\n * generatorParameters({\n * w: checkParameters([0.40255])\n * });\n * } catch (e: any) {\n * alert(e);\n * }\n */\nexport const checkParameters = (parameters: number[] | readonly number[]) => {\n const invalid = parameters.find(\n (param) => !Number.isFinite(param) && !Number.isNaN(param)\n )\n if (invalid !== undefined) {\n throw Error(`Non-finite or NaN value in parameters ${parameters}`)\n } else if (![17, 19, 21].includes(parameters.length)) {\n throw Error(\n `Invalid parameter length: ${parameters.length}. Must be 17, 19 or 21 for FSRSv4, 5 and 6 respectively.`\n )\n }\n return parameters\n}\n\nexport const migrateParameters = (\n parameters?: number[] | readonly number[],\n numRelearningSteps: number = 0,\n enableShortTerm: boolean = default_enable_short_term\n) => {\n if (parameters === undefined) {\n return [...default_w]\n }\n switch (parameters.length) {\n case 21:\n return clipParameters(\n Array.from(parameters),\n numRelearningSteps,\n enableShortTerm\n )\n case 19:\n console.debug('[FSRS-6]auto fill w from 19 to 21 length')\n return clipParameters(\n Array.from(parameters),\n numRelearningSteps,\n enableShortTerm\n ).concat([0.0, FSRS5_DEFAULT_DECAY])\n case 17: {\n const w = clipParameters(\n Array.from(parameters),\n numRelearningSteps,\n enableShortTerm\n )\n w[4] = +(w[5] * 2.0 + w[4]).toFixed(8)\n w[5] = +(Math.log(w[5] * 3.0 + 1.0) / 3.0).toFixed(8)\n w[6] = +(w[6] + 0.5).toFixed(8)\n console.debug('[FSRS-6]auto fill w from 17 to 21 length')\n return w.concat([0.0, 0.0, 0.0, FSRS5_DEFAULT_DECAY])\n }\n default:\n // To throw use \"checkParameters\"\n // ref: https://github.com/open-spaced-repetition/ts-fsrs/pull/174#discussion_r2070436201\n console.warn('[FSRS]Invalid parameters length, using default parameters')\n return [...default_w]\n }\n}\n\nexport const generatorParameters = (\n props?: Partial<FSRSParameters>\n): FSRSParameters => {\n const learning_steps = Array.isArray(props?.learning_steps)\n ? props!.learning_steps\n : default_learning_steps\n const relearning_steps = Array.isArray(props?.relearning_steps)\n ? props!.relearning_steps\n : default_relearning_steps\n const enable_short_term =\n props?.enable_short_term ?? default_enable_short_term\n const w = migrateParameters(\n props?.w,\n relearning_steps.length,\n enable_short_term\n )\n\n return {\n request_retention: props?.request_retention || default_request_retention,\n maximum_interval: props?.maximum_interval || default_maximum_interval,\n w: w,\n enable_fuzz: props?.enable_fuzz ?? default_enable_fuzz,\n enable_short_term: enable_short_term,\n learning_steps: learning_steps,\n relearning_steps: relearning_steps,\n } satisfies FSRSParameters\n}\n\n/**\n * Create an empty card\n * @param now Current time\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * ```\n * @example\n * ```typescript\n * interface CardUnChecked\n * extends Omit<Card, \"due\" | \"last_review\" | \"state\"> {\n * cid: string;\n * due: Date | number;\n * last_review: Date | null | number;\n * state: StateType;\n * }\n *\n * function cardAfterHandler(card: Card) {\n * return {\n * ...card,\n * cid: \"test001\",\n * state: State[card.state],\n * last_review: card.last_review ?? null,\n * } as CardUnChecked;\n * }\n *\n * const card: CardUnChecked = createEmptyCard(new Date(), cardAfterHandler);\n * ```\n */\nexport function createEmptyCard<R = Card>(\n now?: DateInput,\n afterHandler?: (card: Card) => R\n): R {\n const emptyCard: Card = {\n due: now ? TypeConvert.time(now) : new Date(),\n stability: 0,\n difficulty: 0,\n elapsed_days: 0,\n scheduled_days: 0,\n reps: 0,\n lapses: 0,\n learning_steps: 0,\n state: State.New,\n last_review: undefined,\n }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(emptyCard)\n } else {\n return emptyCard as R\n }\n}\n","import { alea } from './alea'\nimport { S_MIN } from './constant'\nimport { generatorParameters, migrateParameters } from './default'\nimport { clamp, get_fuzz_range } from './help'\nimport {\n type FSRSParameters,\n type FSRSState,\n type Grade,\n Rating,\n} from './models'\nimport type { int } from './types'\n/**\n * $$\\text{decay} = -w_{20}$$\n *\n * $$\\text{factor} = e^{\\frac{\\ln 0.9}{\\text{decay}}} - 1$$\n */\nexport const computeDecayFactor = (\n decayOrParams: number | number[] | readonly number[]\n) => {\n const decay =\n typeof decayOrParams === 'number' ? -decayOrParams : -decayOrParams[20]\n const factor = Math.exp(Math.pow(decay, -1) * Math.log(0.9)) - 1.0\n return { decay, factor: +factor.toFixed(8) }\n}\n\n/**\n * The formula used is :\n * $$R(t,S) = (1 + \\text{FACTOR} \\times \\frac{t}{9 \\cdot S})^{\\text{DECAY}}$$\n * @param {number} decay - The decay factor, decay should be greater than or equal to 0.1 and less than or equal to 0.8.\n * @param {number} elapsed_days t days since the last review\n * @param {number} stability Stability (interval when R=90%)\n * @return {number} r Retrievability (probability of recall)\n */\nexport function forgetting_curve(\n decay: number,\n elapsed_days: number,\n stability: number\n): number\nexport function forgetting_curve(\n parameters: number[] | readonly number[],\n elapsed_days: number,\n stability: number\n): number\nexport function forgetting_curve(\n decayOrParams: number | number[] | readonly number[],\n elapsed_days: number,\n stability: number\n): number {\n const { decay, factor } = computeDecayFactor(decayOrParams)\n return +Math.pow(1 + (factor * elapsed_days) / stability, decay).toFixed(8)\n}\n\n/**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm#fsrs-45\n */\nexport class FSRSAlgorithm {\n protected param!: FSRSParameters\n protected intervalModifier!: number\n protected _seed?: string\n\n constructor(params: Partial<FSRSParameters>) {\n this.param = new Proxy(\n generatorParameters(params),\n this.params_handler_proxy()\n )\n this.intervalModifier = this.calculate_interval_modifier(\n this.param.request_retention\n )\n this.forgetting_curve = forgetting_curve.bind(this, this.param.w)\n }\n\n get interval_modifier(): number {\n return this.intervalModifier\n }\n\n set seed(seed: string) {\n this._seed = seed\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm#fsrs-5\n *\n * The formula used is: $$I(r,s) = (r^{\\frac{1}{DECAY}} - 1) / FACTOR \\times s$$\n * @param request_retention 0<request_retention<=1,Requested retention rate\n * @throws {Error} Requested retention rate should be in the range (0,1]\n */\n calculate_interval_modifier(request_retention: number): number {\n if (request_retention <= 0 || request_retention > 1) {\n throw new Error('Requested retention rate should be in the range (0,1]')\n }\n const { decay, factor } = computeDecayFactor(this.param.w)\n return +((Math.pow(request_retention, 1 / decay) - 1) / factor).toFixed(8)\n }\n\n /**\n * Get the parameters of the algorithm.\n */\n get parameters(): FSRSParameters {\n return this.param\n }\n\n /**\n * Set the parameters of the algorithm.\n * @param params Partial<FSRSParameters>\n */\n set parameters(params: Partial<FSRSParameters>) {\n this.update_parameters(params)\n }\n\n protected params_handler_proxy(): ProxyHandler<FSRSParameters> {\n const _this = this satisfies FSRSAlgorithm\n return {\n set: function (\n target: FSRSParameters,\n prop: keyof FSRSParameters,\n value: FSRSParameters[keyof FSRSParameters]\n ) {\n if (prop === 'request_retention' && Number.isFinite(value)) {\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(value)\n )\n } else if (prop === 'w') {\n value = migrateParameters(\n value as FSRSParameters['w'],\n target.relearning_steps.length,\n target.enable_short_term\n )\n _this.forgetting_curve = forgetting_curve.bind(this, value)\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(target.request_retention)\n )\n }\n Reflect.set(target, prop, value)\n return true\n },\n }\n }\n\n private update_parameters(params: Partial<FSRSParameters>): void {\n const _params = generatorParameters(params)\n for (const key in _params) {\n // All keys in _params are guaranteed to exist in this.param due to generatorParameters()\n const paramKey = key as keyof FSRSParameters\n this.param[paramKey] = _params[paramKey] as never\n }\n }\n\n /**\n * The formula used is :\n * $$ S_0(G) = w_{G-1}$$\n * $$S_0 = \\max \\lbrace S_0,0.1\\rbrace $$\n\n * @param g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return Stability (interval when R=90%)\n */\n init_stability(g: Grade): number {\n return Math.max(this.param.w[g - 1], 0.1)\n }\n\n /**\n * The formula used is :\n * $$D_0(G) = w_4 - e^{(G-1) \\cdot w_5} + 1 $$\n * $$D_0 = \\min \\lbrace \\max \\lbrace D_0(G),1 \\rbrace,10 \\rbrace$$\n * where the $$D_0(1)=w_4$$ when the first rating is good.\n *\n * @param {Grade} g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return {number} Difficulty $$D \\in [1,10]$$\n */\n init_difficulty(g: Grade): number {\n const d = this.param.w[4] - Math.exp((g - 1) * this.param.w[5]) + 1\n return +d.toFixed(8)\n }\n\n /**\n * If fuzzing is disabled or ivl is less than 2.5, it returns the original interval.\n * @param {number} ivl - The interval to be fuzzed.\n * @param {number} elapsed_days t days since the last review\n * @return {number} - The fuzzed interval.\n **/\n apply_fuzz(ivl: number, elapsed_days: number): int {\n if (!this.param.enable_fuzz || ivl < 2.5) return Math.round(ivl) as int\n const generator = alea(this._seed) // I do not want others to directly access the seed externally.\n const fuzz_factor = generator()\n const { min_ivl, max_ivl } = get_fuzz_range(\n ivl,\n elapsed_days,\n this.param.maximum_interval\n )\n return Math.floor(fuzz_factor * (max_ivl - min_ivl + 1) + min_ivl) as int\n }\n\n /**\n * @see The formula used is : {@link FSRSAlgorithm.calculate_interval_modifier}\n * @param {number} s - Stability (interval when R=90%)\n * @param {number} elapsed_days t days since the last review\n */\n next_interval(s: number, elapsed_days: number): int {\n const newInterval = Math.min(\n Math.max(1, Math.round(s * this.intervalModifier)),\n this.param.maximum_interval\n ) as int\n return this.apply_fuzz(newInterval, elapsed_days)\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/fsrs4anki/issues/697\n */\n linear_damping(delta_d: number, old_d: number): number {\n return +((delta_d * (10 - old_d)) / 9).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$\\text{delta}_d = -w_6 \\cdot (g - 3)$$\n * $$\\text{next}_d = D + \\text{linear damping}(\\text{delta}_d , D)$$\n * $$D^\\prime(D,R) = w_7 \\cdot D_0(4) +(1 - w_7) \\cdot \\text{next}_d$$\n * @param {number} d Difficulty $$D \\in [1,10]$$\n * @param {Grade} g Grade (rating at Anki) [1.again,2.hard,3.good,4.easy]\n * @return {number} $$\\text{next}_D$$\n */\n next_difficulty(d: number, g: Grade): number {\n const delta_d = -this.param.w[6] * (g - 3)\n const next_d = d + this.linear_damping(delta_d, d)\n return clamp(\n this.mean_reversion(this.init_difficulty(Rating.Easy), next_d),\n 1,\n 10\n )\n }\n\n /**\n * The formula used is :\n * $$w_7 \\cdot \\text{init} +(1 - w_7) \\cdot \\text{current}$$\n * @param {number} init $$w_2 : D_0(3) = w_2 + (R-2) \\cdot w_3= w_2$$\n * @param {number} current $$D - w_6 \\cdot (R - 2)$$\n * @return {number} difficulty\n */\n mean_reversion(init: number, current: number): number {\n return +(this.param.w[7] * init + (1 - this.param.w[7]) * current).toFixed(\n 8\n )\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_r(D,S,R,G) = S\\cdot(e^{w_8}\\cdot (11-D)\\cdot S^{-w_9}\\cdot(e^{w_{10}\\cdot(1-R)}-1)\\cdot w_{15}(\\text{if} G=2) \\cdot w_{16}(\\text{if} G=4)+1)$$\n * @param {number} d Difficulty D \\in [1,10]\n * @param {number} s Stability (interval when R=90%)\n * @param {number} r Retrievability (probability of recall)\n * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])\n * @return {number} S^\\prime_r new stability after recall\n */\n next_recall_stability(d: number, s: number, r: number, g: Grade): number {\n const hard_penalty = Rating.Hard === g ? this.param.w[15] : 1\n const easy_bound = Rating.Easy === g ? this.param.w[16] : 1\n return +clamp(\n s *\n (1 +\n Math.exp(this.param.w[8]) *\n (11 - d) *\n Math.pow(s, -this.param.w[9]) *\n (Math.exp((1 - r) * this.param.w[10]) - 1) *\n hard_penalty *\n easy_bound),\n S_MIN,\n 36500.0\n ).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_f(D,S,R) = w_{11}\\cdot D^{-w_{12}}\\cdot ((S+1)^{w_{13}}-1) \\cdot e^{w_{14}\\cdot(1-R)}$$\n * enable_short_term = true : $$S^\\prime_f \\in \\min \\lbrace \\max \\lbrace S^\\prime_f,0.01\\rbrace, \\frac{S}{e^{w_{17} \\cdot w_{18}}} \\rbrace$$\n * enable_short_term = false : $$S^\\prime_f \\in \\min \\lbrace \\max \\lbrace S^\\prime_f,0.01\\rbrace, S \\rbrace$$\n * @param {number} d Difficulty D \\in [1,10]\n * @param {number} s Stability (interval when R=90%)\n * @param {number} r Retrievability (probability of recall)\n * @return {number} S^\\prime_f new stability after forgetting\n */\n next_forget_stability(d: number, s: number, r: number): number {\n return +clamp(\n this.param.w[11] *\n Math.pow(d, -this.param.w[12]) *\n (Math.pow(s + 1, this.param.w[13]) - 1) *\n Math.exp((1 - r) * this.param.w[14]),\n S_MIN,\n 36500.0\n ).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$S^\\prime_s(S,G) = S \\cdot e^{w_{17} \\cdot (G-3+w_{18})}$$\n * @param {number} s Stability (interval when R=90%)\n * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])\n */\n next_short_term_stability(s: number, g: Grade): number {\n const sinc =\n Math.pow(s, -this.param.w[19]) *\n Math.exp(this.param.w[17] * (g - 3 + this.param.w[18]))\n\n const maskedSinc = g >= 3 ? Math.max(sinc, 1.0) : sinc\n return +clamp(s * maskedSinc, S_MIN, 36500.0).toFixed(8)\n }\n\n /**\n * The formula used is :\n * $$R(t,S) = (1 + \\text{FACTOR} \\times \\frac{t}{9 \\cdot S})^{\\text{DECAY}}$$\n * @param {number} elapsed_days t days since the last review\n * @param {number} stability Stability (interval when R=90%)\n * @return {number} r Retrievability (probability of recall)\n */\n forgetting_curve: (elapsed_days: number, stability: number) => number\n /**\n * Calculates the next state of memory based on the current state, time elapsed, and grade.\n *\n * @param memory_state - The current state of memory, which can be null.\n * @param t - The time elapsed since the last review.\n * @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])\n * @returns The next state of memory with updated difficulty and stability.\n */\n next_state(memory_state: FSRSState | null, t: number, g: number): FSRSState {\n const { difficulty: d, stability: s } = memory_state ?? {\n difficulty: 0,\n stability: 0,\n }\n if (t < 0) {\n throw new Error(`Invalid delta_t \"${t}\"`)\n }\n if (g < 0 || g > 4) {\n throw new Error(`Invalid grade \"${g}\"`)\n }\n if (d === 0 && s === 0) {\n return {\n difficulty: clamp(this.init_difficulty(g), 1, 10),\n stability: this.init_stability(g),\n }\n }\n if (g === 0) {\n return {\n difficulty: d,\n stability: s,\n }\n }\n if (d < 1 || s < S_MIN) {\n throw new Error(\n `Invalid memory state { difficulty: ${d}, stability: ${s} }`\n )\n }\n const r = this.forgetting_curve(t, s)\n const s_after_success = this.next_recall_stability(d, s, r, g)\n const s_after_fail = this.next_forget_stability(d, s, r)\n const s_after_short_term = this.next_short_term_stability(s, g)\n let new_s = s_after_success\n if (g === 1) {\n let [w_17, w_18] = [0, 0]\n if (this.param.enable_short_term) {\n w_17 = this.param.w[17]\n w_18 = this.param.w[18]\n }\n const next_s_min = s / Math.exp(w_17 * w_18)\n new_s = clamp(+next_s_min.toFixed(8), S_MIN, s_after_fail)\n }\n if (t === 0 && this.param.enable_short_term) {\n new_s = s_after_short_term\n }\n\n const new_d = this.next_difficulty(d, g)\n return { difficulty: new_d, stability: new_s }\n }\n}\n","import { AbstractScheduler } from '../abstract_scheduler'\nimport type { FSRSAlgorithm } from '../algorithm'\nimport { S_MIN } from '../constant'\nimport { TypeConvert } from '../convert'\nimport { clamp, date_scheduler } from '../help'\nimport {\n type Card,\n type CardInput,\n type DateInput,\n type Grade,\n Rating,\n type RecordLogItem,\n State,\n} from '../models'\nimport {\n StrategyMode,\n type TLearningStepsStrategy,\n type TStrategyHandler,\n} from '../strategies'\nimport { BasicLearningStepsStrategy } from '../strategies/learning_steps'\nimport type { int } from '../types'\n\nexport default class BasicScheduler extends AbstractScheduler {\n private learningStepsStrategy: TLearningStepsStrategy\n\n constructor(\n card: CardInput | Card,\n now: DateInput,\n algorithm: FSRSAlgorithm,\n strategies?: Map<StrategyMode, TStrategyHandler>\n ) {\n super(card, now, algorithm, strategies)\n\n // init learning steps strategy\n let learningStepStrategy = BasicLearningStepsStrategy\n if (this.strategies) {\n const custom_strategy = this.strategies.get(StrategyMode.LEARNING_STEPS)\n if (custom_strategy) {\n learningStepStrategy = custom_strategy as TLearningStepsStrategy\n }\n }\n this.learningStepsStrategy = learningStepStrategy\n }\n\n private getLearningInfo(card: Card, grade: Grade) {\n const parameters = this.algorithm.parameters\n card.learning_steps = card.learning_steps || 0\n const steps_strategy = this.learningStepsStrategy(\n parameters,\n card.state,\n // In the original learning steps setup (Again = 5m, Hard = 10m, Good = FSRS),\n // not adding 1 can cause slight variations in the memory state’s ds.\n this.current.state === State.Learning &&\n grade !== Rating.Again &&\n grade !== Rating.Hard\n ? card.learning_steps + 1\n : card.learning_steps\n )\n const scheduled_minutes = Math.max(\n 0,\n steps_strategy[grade]?.scheduled_minutes ?? 0\n )\n const next_steps = Math.max(0, steps_strategy[grade]?.next_step ?? 0)\n return {\n scheduled_minutes,\n next_steps,\n }\n }\n /**\n * @description This function applies the learning steps based on the current card's state and grade.\n */\n private applyLearningSteps(\n nextCard: Card,\n grade: Grade,\n /**\n * returns the next state for the card (if applicable)\n */\n to_state: State\n ) {\n const { scheduled_minutes, next_steps } = this.getLearningInfo(\n this.current,\n grade\n )\n if (\n scheduled_minutes > 0 &&\n scheduled_minutes < 1440 /** 1440 minutes = 1 day */\n ) {\n nextCard.learning_steps = next_steps\n nextCard.scheduled_days = 0\n nextCard.state = to_state\n nextCard.due = date_scheduler(\n this.review_time,\n Math.round(scheduled_minutes) as int,\n false /** true:days false: minute */\n )\n } else {\n nextCard.state = State.Review\n if (scheduled_minutes >= 1440) {\n nextCard.learning_steps = next_steps\n nextCard.due = date_scheduler(\n this.review_time,\n Math.round(scheduled_minutes) as int,\n false /** true:days false: minute */\n )\n nextCard.scheduled_days = Math.floor(scheduled_minutes / 1440)\n } else {\n nextCard.learning_steps = 0\n const interval = this.algorithm.next_interval(\n nextCard.stability,\n this.elapsed_days\n )\n nextCard.scheduled_days = interval\n nextCard.due = date_scheduler(this.review_time, interval as int, true)\n }\n }\n }\n\n protected override newState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const next = TypeConvert.card(this.current)\n next.difficulty = clamp(this.algorithm.init_difficulty(grade), 1, 10)\n next.stability = this.algorithm.init_stability(grade)\n\n this.applyLearningSteps(next, grade, State.Learning)\n const item = {\n card: next,\n log: this.buildLog(grade),\n } satisfies RecordLogItem\n this.next.set(grade, item)\n return item\n }\n\n protected override learningState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const { state, difficulty, stability } = this.last\n const next = TypeConvert.card(this.current)\n next.difficulty = this.algorithm.next_difficulty(difficulty, grade)\n next.stability = this.algorithm.next_short_term_stability(stability, grade)\n this.applyLearningSteps(next, grade, state /** Learning or Relearning */)\n const item = {\n card: next,\n log: this.buildLog(grade),\n } satisfies RecordLogItem\n this.next.set(grade, item)\n return item\n }\n\n protected override reviewState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const interval = this.elapsed_days\n const { difficulty, stability } = this.last\n const retrievability = this.algorithm.forgetting_curve(interval, stability)\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.next_ds(\n next_again,\n next_hard,\n next_good,\n next_easy,\n difficulty,\n stability,\n retrievability\n )\n\n this.next_interval(next_hard, next_good, next_easy, interval)\n this.next_state(next_hard, next_good, next_easy)\n this.applyLearningSteps(next_again, Rating.Again, State.Relearning)\n next_again.lapses += 1\n\n const item_again = {\n card: next_again,\n log: this.buildLog(Rating.Again),\n } satisfies RecordLogItem\n const item_hard = {\n card: next_hard,\n log: super.buildLog(Rating.Hard),\n } satisfies RecordLogItem\n const item_good = {\n card: next_good,\n log: super.buildLog(Rating.Good),\n } satisfies RecordLogItem\n const item_easy = {\n card: next_easy,\n log: super.buildLog(Rating.Easy),\n } satisfies RecordLogItem\n\n this.next.set(Rating.Again, item_again)\n this.next.set(Rating.Hard, item_hard)\n this.next.set(Rating.Good, item_good)\n this.next.set(Rating.Easy, item_easy)\n return this.next.get(grade)!\n }\n\n /**\n * Review next_ds\n */\n private next_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n difficulty: number,\n stability: number,\n retrievability: number\n ): void {\n next_again.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Again\n )\n const nextSMin =\n stability /\n Math.exp(\n this.algorithm.parameters.w[17] * this.algorithm.parameters.w[18]\n )\n const s_after_fail = this.algorithm.next_forget_stability(\n difficulty,\n stability,\n retrievability\n )\n next_again.stability = clamp(+nextSMin.toFixed(8), S_MIN, s_after_fail)\n\n next_hard.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Hard\n )\n next_hard.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Hard\n )\n next_good.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Good\n )\n next_good.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Good\n )\n next_easy.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Easy\n )\n next_easy.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Easy\n )\n }\n\n /**\n * Review next_interval\n */\n private next_interval(\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n interval: number\n ): void {\n let hard_interval: int, good_interval: int\n hard_interval = this.algorithm.next_interval(next_hard.stability, interval)\n good_interval = this.algorithm.next_interval(next_good.stability, interval)\n hard_interval = Math.min(hard_interval, good_interval) as int\n good_interval = Math.max(good_interval, hard_interval + 1) as int\n const easy_interval = Math.max(\n this.algorithm.next_interval(next_easy.stability, interval),\n good_interval + 1\n ) as int\n\n next_hard.scheduled_days = hard_interval\n next_hard.due = date_scheduler(this.review_time, hard_interval, true)\n next_good.scheduled_days = good_interval\n next_good.due = date_scheduler(this.review_time, good_interval, true)\n\n next_easy.scheduled_days = easy_interval\n next_easy.due = date_scheduler(this.review_time, easy_interval, true)\n }\n\n /**\n * Review next_state\n */\n private next_state(next_hard: Card, next_good: Card, next_easy: Card) {\n next_hard.state = State.Review\n next_hard.learning_steps = 0\n\n next_good.state = State.Review\n next_good.learning_steps = 0\n\n next_easy.state = State.Review\n next_easy.learning_steps = 0\n }\n}\n","import { AbstractScheduler } from '../abstract_scheduler'\nimport { S_MIN } from '../constant'\nimport { TypeConvert } from '../convert'\nimport { clamp, date_scheduler } from '../help'\nimport {\n type Card,\n type Grade,\n Rating,\n type RecordLogItem,\n State,\n} from '../models'\nimport type { int } from '../types'\n\nexport default class LongTermScheduler extends AbstractScheduler {\n protected override newState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n\n this.current.scheduled_days = 0\n // pending removal in v6.0.0\n this.current.elapsed_days = 0\n\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.init_ds(next_again, next_hard, next_good, next_easy)\n const first_interval = 0\n\n this.next_interval(\n next_again,\n next_hard,\n next_good,\n next_easy,\n first_interval\n )\n\n this.next_state(next_again, next_hard, next_good, next_easy)\n this.update_next(next_again, next_hard, next_good, next_easy)\n return this.next.get(grade)!\n }\n\n private init_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ): void {\n next_again.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Again),\n 1,\n 10\n )\n next_again.stability = this.algorithm.init_stability(Rating.Again)\n\n next_hard.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Hard),\n 1,\n 10\n )\n next_hard.stability = this.algorithm.init_stability(Rating.Hard)\n\n next_good.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Good),\n 1,\n 10\n )\n next_good.stability = this.algorithm.init_stability(Rating.Good)\n\n next_easy.difficulty = clamp(\n this.algorithm.init_difficulty(Rating.Easy),\n 1,\n 10\n )\n next_easy.stability = this.algorithm.init_stability(Rating.Easy)\n }\n\n /**\n * @see https://github.com/open-spaced-repetition/ts-fsrs/issues/98#issuecomment-2241923194\n */\n protected override learningState(grade: Grade): RecordLogItem {\n return this.reviewState(grade)\n }\n protected override reviewState(grade: Grade): RecordLogItem {\n const exist = this.next.get(grade)\n if (exist) {\n return exist\n }\n const interval = this.elapsed_days\n const { difficulty, stability } = this.last\n const retrievability = this.algorithm.forgetting_curve(interval, stability)\n const next_again = TypeConvert.card(this.current)\n const next_hard = TypeConvert.card(this.current)\n const next_good = TypeConvert.card(this.current)\n const next_easy = TypeConvert.card(this.current)\n\n this.next_ds(\n next_again,\n next_hard,\n next_good,\n next_easy,\n difficulty,\n stability,\n retrievability\n )\n\n this.next_interval(next_again, next_hard, next_good, next_easy, interval)\n this.next_state(next_again, next_hard, next_good, next_easy)\n next_again.lapses += 1\n\n this.update_next(next_again, next_hard, next_good, next_easy)\n return this.next.get(grade)!\n }\n\n /**\n * Review next_ds\n */\n private next_ds(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n difficulty: number,\n stability: number,\n retrievability: number\n ): void {\n next_again.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Again\n )\n const s_after_fail = this.algorithm.next_forget_stability(\n difficulty,\n stability,\n retrievability\n )\n next_again.stability = clamp(stability, S_MIN, s_after_fail)\n\n next_hard.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Hard\n )\n next_hard.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Hard\n )\n next_good.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Good\n )\n next_good.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Good\n )\n next_easy.difficulty = this.algorithm.next_difficulty(\n difficulty,\n Rating.Easy\n )\n next_easy.stability = this.algorithm.next_recall_stability(\n difficulty,\n stability,\n retrievability,\n Rating.Easy\n )\n }\n\n /**\n * Review/New next_interval\n */\n private next_interval(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card,\n interval: number\n ): void {\n let again_interval: int,\n hard_interval: int,\n good_interval: int,\n easy_interval: int\n again_interval = this.algorithm.next_interval(\n next_again.stability,\n interval\n )\n hard_interval = this.algorithm.next_interval(next_hard.stability, interval)\n good_interval = this.algorithm.next_interval(next_good.stability, interval)\n easy_interval = this.algorithm.next_interval(next_easy.stability, interval)\n\n again_interval = Math.min(again_interval, hard_interval) as int\n hard_interval = Math.max(hard_interval, again_interval + 1) as int\n good_interval = Math.max(good_interval, hard_interval + 1) as int\n easy_interval = Math.max(easy_interval, good_interval + 1) as int\n\n next_again.scheduled_days = again_interval\n next_again.due = date_scheduler(this.review_time, again_interval, true)\n\n next_hard.scheduled_days = hard_interval\n next_hard.due = date_scheduler(this.review_time, hard_interval, true)\n\n next_good.scheduled_days = good_interval\n next_good.due = date_scheduler(this.review_time, good_interval, true)\n\n next_easy.scheduled_days = easy_interval\n next_easy.due = date_scheduler(this.review_time, easy_interval, true)\n }\n\n /**\n * Review/New next_state\n */\n private next_state(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ) {\n next_again.state = State.Review\n // next_again.lapses += 1\n next_again.learning_steps = 0\n\n next_hard.state = State.Review\n next_hard.learning_steps = 0\n\n next_good.state = State.Review\n next_good.learning_steps = 0\n\n next_easy.state = State.Review\n next_easy.learning_steps = 0\n }\n\n private update_next(\n next_again: Card,\n next_hard: Card,\n next_good: Card,\n next_easy: Card\n ) {\n const item_again = {\n card: next_again,\n log: this.buildLog(Rating.Again),\n } satisfies RecordLogItem\n const item_hard = {\n card: next_hard,\n log: super.buildLog(Rating.Hard),\n } satisfies RecordLogItem\n const item_good = {\n card: next_good,\n log: super.buildLog(Rating.Good),\n } satisfies RecordLogItem\n const item_easy = {\n card: next_easy,\n log: super.buildLog(Rating.Easy),\n } satisfies RecordLogItem\n\n this.next.set(Rating.Again, item_again)\n this.next.set(Rating.Hard, item_hard)\n this.next.set(Rating.Good, item_good)\n this.next.set(Rating.Easy, item_easy)\n }\n}\n","import { TypeConvert } from './convert'\nimport { createEmptyCard } from './default'\nimport type { FSRS } from './fsrs'\nimport { date_diff } from './help'\nimport {\n type Card,\n type CardInput,\n type DateInput,\n type FSRSHistory,\n type Grade,\n Rating,\n type RecordLogItem,\n type ReviewLog,\n State,\n} from './models'\n\n/**\n * The `Reschedule` class provides methods to handle the rescheduling of cards based on their review history.\n * determine the next review dates and update the card's state accordingly.\n */\nexport class Reschedule {\n private fsrs: FSRS\n /**\n * Creates an instance of the `Reschedule` class.\n * @param fsrs - An instance of the FSRS class used for scheduling.\n */\n constructor(fsrs: FSRS) {\n this.fsrs = fsrs\n }\n\n /**\n * Replays a review for a card and determines the next review date based on the given rating.\n * @param card - The card being reviewed.\n * @param reviewed - The date the card was reviewed.\n * @param rating - The grade given to the card during the review.\n * @returns A `RecordLogItem` containing the updated card and review log.\n */\n replay(card: Card, reviewed: Date, rating: Grade): RecordLogItem {\n return this.fsrs.next(card, reviewed, rating)\n }\n\n /**\n * Processes a manual review for a card, allowing for custom state, stability, difficulty, and due date.\n * @param card - The card being reviewed.\n * @param state - The state of the card after the review.\n * @param reviewed - The date the card was reviewed.\n * @param elapsed_days - The number of days since the last review.\n * @param stability - (Optional) The stability of the card.\n * @param difficulty - (Optional) The difficulty of the card.\n * @param due - (Optional) The due date for the next review.\n * @returns A `RecordLogItem` containing the updated card and review log.\n * @throws Will throw an error if the state or due date is not provided when required.\n */\n handleManualRating(\n card: Card,\n state: State,\n reviewed: Date,\n elapsed_days: number,\n stability?: number,\n difficulty?: number,\n due?: Date\n ): RecordLogItem {\n if (typeof state === 'undefined') {\n throw new Error('reschedule: state is required for manual rating')\n }\n let log: ReviewLog\n let next_card: Card\n if (<State>state === State.New) {\n log = {\n rating: Rating.Manual,\n state: state,\n due: <Date>due ?? reviewed,\n stability: card.stability,\n difficulty: card.difficulty,\n elapsed_days: elapsed_days,\n last_elapsed_days: card.elapsed_days,\n scheduled_days: card.scheduled_days,\n learning_steps: card.learning_steps,\n review: <Date>reviewed,\n } satisfies ReviewLog\n next_card = createEmptyCard<Card>(reviewed)\n next_card.last_review = reviewed\n } else {\n if (typeof due === 'undefined') {\n throw new Error('reschedule: due is required for manual rating')\n }\n const scheduled_days = date_diff(due, reviewed, 'days')\n log = {\n rating: Rating.Manual,\n state: <State>card.state,\n due: card.last_review || card.due,\n stability: card.stability,\n difficulty: card.difficulty,\n elapsed_days: elapsed_days,\n last_elapsed_days: card.elapsed_days,\n scheduled_days: card.scheduled_days,\n learning_steps: card.learning_steps,\n review: <Date>reviewed,\n } satisfies ReviewLog\n next_card = {\n ...card,\n state: <State>state,\n due: <Date>due,\n last_review: <Date>reviewed,\n stability: stability || card.stability,\n difficulty: difficulty || card.difficulty,\n elapsed_days: elapsed_days,\n scheduled_days: scheduled_days,\n reps: card.reps + 1,\n } satisfies Card\n }\n\n return { card: next_card, log }\n }\n\n /**\n * Reschedules a card based on its review history.\n *\n * @param current_card - The card to be rescheduled.\n * @param reviews - An array of review history objects.\n * @returns An array of record log items representing the rescheduling process.\n */\n reschedule(current_card: CardInput, reviews: FSRSHistory[]) {\n const collections: RecordLogItem[] = []\n let cur_card = createEmptyCard<Card>(current_card.due)\n for (const review of reviews) {\n let item: RecordLogItem\n review.review = TypeConvert.time(review.review)\n if (review.rating === Rating.Manual) {\n // ref: abstract_scheduler.ts#init\n let interval = 0\n if (cur_card.state !== State.New && cur_card.last_review) {\n interval = date_diff(review.review, cur_card.last_review, 'days')\n }\n item = this.handleManualRating(\n cur_card,\n review.state,\n review.review,\n interval,\n review.stability,\n review.difficulty,\n review.due ? TypeConvert.time(review.due) : undefined\n )\n } else {\n item = this.replay(cur_card, review.review, review.rating)\n }\n collections.push(item)\n cur_card = item.card\n }\n return collections\n }\n\n calculateManualRecord(\n current_card: CardInput,\n now: DateInput,\n record_log_item?: RecordLogItem,\n update_memory?: boolean\n ): RecordLogItem | null {\n if (!record_log_item) {\n return null\n }\n // if first_card === recordItem.card then return null\n const { card: reschedule_card, log } = record_log_item\n const cur_card = <Card>TypeConvert.card(current_card) // copy card\n if (cur_card.due.getTime() === reschedule_card.due.getTime()) {\n return null\n }\n cur_card.scheduled_days = date_diff(\n reschedule_card.due,\n cur_card.due,\n 'days'\n )\n return this.handleManualRating(\n cur_card,\n reschedule_card.state,\n TypeConvert.time(now),\n log.elapsed_days,\n update_memory ? reschedule_card.stability : undefined,\n update_memory ? reschedule_card.difficulty : undefined,\n reschedule_card.due\n )\n }\n}\n","import { FSRSAlgorithm, forgetting_curve } from './algorithm'\nimport { TypeConvert } from './convert'\nimport { createEmptyCard, migrateParameters } from './default'\nimport { date_diff } from './help'\nimport BasicScheduler from './impl/basic_scheduler'\nimport LongTermScheduler from './impl/long_term_scheduler'\nimport {\n type Card,\n type CardInput,\n type DateInput,\n type FSRSHistory,\n type FSRSParameters,\n type Grade,\n Rating,\n type RecordLogItem,\n type ReviewLog,\n type ReviewLogInput,\n State,\n} from './models'\nimport { Reschedule } from './reschedule'\nimport {\n StrategyMode,\n type TSchedulerStrategy,\n type TStrategyHandler,\n} from './strategies/types'\nimport type {\n IPreview,\n IReschedule,\n IScheduler,\n RescheduleOptions,\n} from './types'\n\n// A utility type to require only K properties of A\ntype RequireOnly<A, K extends keyof A> = { [P in K]-?: A[P] } & Partial<\n Omit<A, K>\n>\n\nexport interface IFSRS {\n useStrategy<T extends StrategyMode>(\n mode: T,\n handler: TStrategyHandler<T>\n ): this\n\n clearStrategy(mode?: StrategyMode): this\n\n repeat(card: CardInput | Card, now: DateInput): IPreview\n repeat<R>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler: (recordLog: IPreview) => R\n ): R\n\n next(card: CardInput | Card, now: DateInput, grade: Grade): RecordLogItem\n next<R>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler: (recordLog: RecordLogItem) => R\n ): R\n\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: true\n ): string\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: false\n ): number\n\n rollback(card: CardInput | Card, log: ReviewLogInput): Card\n rollback<R>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler: (prevCard: Card) => R\n ): R\n\n forget(\n card: CardInput | Card,\n now: DateInput,\n reset_count?: boolean\n ): RecordLogItem\n forget<R>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean | undefined,\n afterHandler: (recordLogItem: RecordLogItem) => R\n ): R\n\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: RequireOnly<RescheduleOptions<T>, 'recordLogHandler'>\n ): IReschedule<T>\n reschedule(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: Partial<RescheduleOptions<RecordLogItem>>\n ): IReschedule<RecordLogItem>\n}\n\nexport class FSRS extends FSRSAlgorithm implements IFSRS {\n private strategyHandler = new Map<StrategyMode, TStrategyHandler>()\n private Scheduler: TSchedulerStrategy\n constructor(param: Partial<FSRSParameters>) {\n super(param)\n const { enable_short_term } = this.parameters\n this.Scheduler = enable_short_term ? BasicScheduler : LongTermScheduler\n }\n\n protected override params_handler_proxy(): ProxyHandler<FSRSParameters> {\n const _this = this satisfies FSRS\n return {\n set: function (\n target: FSRSParameters,\n prop: keyof FSRSParameters,\n value: FSRSParameters[keyof FSRSParameters]\n ) {\n if (prop === 'request_retention' && Number.isFinite(value)) {\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(value)\n )\n } else if (prop === 'enable_short_term') {\n _this.Scheduler = value === true ? BasicScheduler : LongTermScheduler\n } else if (prop === 'w') {\n value = migrateParameters(\n value as FSRSParameters['w'],\n target.relearning_steps.length,\n target.enable_short_term\n )\n _this.forgetting_curve = forgetting_curve.bind(this, value)\n _this.intervalModifier = _this.calculate_interval_modifier(\n Number(target.request_retention)\n )\n }\n Reflect.set(target, prop, value)\n return true\n },\n }\n }\n\n useStrategy<T extends StrategyMode>(\n mode: T,\n handler: TStrategyHandler<T>\n ): this {\n this.strategyHandler.set(mode, handler)\n return this\n }\n\n clearStrategy(mode?: StrategyMode): this {\n if (mode) {\n this.strategyHandler.delete(mode)\n } else {\n this.strategyHandler.clear()\n }\n return this\n }\n\n private getScheduler(card: CardInput | Card, now: DateInput): IScheduler {\n // Strategy scheduler\n const schedulerStrategy = this.strategyHandler.get(\n StrategyMode.SCHEDULER\n ) as TSchedulerStrategy | undefined\n\n const Scheduler = schedulerStrategy || this.Scheduler\n const instance = new Scheduler(card, now, this, this.strategyHandler)\n\n return instance\n }\n\n repeat(card: CardInput | Card, now: DateInput): IPreview\n repeat<R>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler: (recordLog: IPreview) => R\n ): R\n /**\n * Display the collection of cards and logs for the four scenarios after scheduling the card at the current time.\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * const f = fsrs();\n * const recordLog = f.repeat(card, new Date());\n * ```\n * @example\n * ```typescript\n * interface RevLogUnchecked\n * extends Omit<ReviewLog, \"due\" | \"review\" | \"state\" | \"rating\"> {\n * cid: string;\n * due: Date | number;\n * state: StateType;\n * review: Date | number;\n * rating: RatingType;\n * }\n *\n * interface RepeatRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked;\n * }\n *\n * function repeatAfterHandler(recordLog: RecordLog) {\n * const record: { [key in Grade]: RepeatRecordLog } = {} as {\n * [key in Grade]: RepeatRecordLog;\n * };\n * for (const grade of Grades) {\n * record[grade] = {\n * card: {\n * ...(recordLog[grade].card as Card & { cid: string }),\n * due: recordLog[grade].card.due.getTime(),\n * state: State[recordLog[grade].card.state] as StateType,\n * last_review: recordLog[grade].card.last_review\n * ? recordLog[grade].card.last_review!.getTime()\n * : null,\n * },\n * log: {\n * ...recordLog[grade].log,\n * cid: (recordLog[grade].card as Card & { cid: string }).cid,\n * due: recordLog[grade].log.due.getTime(),\n * review: recordLog[grade].log.review.getTime(),\n * state: State[recordLog[grade].log.state] as StateType,\n * rating: Rating[recordLog[grade].log.rating] as RatingType,\n * },\n * };\n * }\n * return record;\n * }\n * const card: Card = createEmptyCard(new Date(), cardAfterHandler); //see method: createEmptyCard\n * const f = fsrs();\n * const recordLog = f.repeat(card, new Date(), repeatAfterHandler);\n * ```\n */\n repeat<R = IPreview>(\n card: CardInput | Card,\n now: DateInput,\n afterHandler?: (recordLog: IPreview) => R\n ): R {\n const instance = this.getScheduler(card, now)\n const recordLog = instance.preview()\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLog)\n } else {\n return recordLog as R\n }\n }\n\n next(card: CardInput | Card, now: DateInput, grade: Grade): RecordLogItem\n next<R>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler: (recordLog: RecordLogItem) => R\n ): R\n /**\n * Display the collection of cards and logs for the card scheduled at the current time, after applying a specific grade rating.\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param grade Rating of the review (Again, Hard, Good, Easy)\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const card: Card = createEmptyCard(new Date());\n * const f = fsrs();\n * const recordLogItem = f.next(card, new Date(), Rating.Again);\n * ```\n * @example\n * ```typescript\n * interface RevLogUnchecked\n * extends Omit<ReviewLog, \"due\" | \"review\" | \"state\" | \"rating\"> {\n * cid: string;\n * due: Date | number;\n * state: StateType;\n * review: Date | number;\n * rating: RatingType;\n * }\n *\n * interface NextRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked;\n * }\n *\n function nextAfterHandler(recordLogItem: RecordLogItem) {\n const recordItem = {\n card: {\n ...(recordLogItem.card as Card & { cid: string }),\n due: recordLogItem.card.due.getTime(),\n state: State[recordLogItem.card.state] as StateType,\n last_review: recordLogItem.card.last_review\n ? recordLogItem.card.last_review!.getTime()\n : null,\n },\n log: {\n ...recordLogItem.log,\n cid: (recordLogItem.card as Card & { cid: string }).cid,\n due: recordLogItem.log.due.getTime(),\n review: recordLogItem.log.review.getTime(),\n state: State[recordLogItem.log.state] as StateType,\n rating: Rating[recordLogItem.log.rating] as RatingType,\n },\n };\n return recordItem\n }\n * const card: Card = createEmptyCard(new Date(), cardAfterHandler); //see method: createEmptyCard\n * const f = fsrs();\n * const recordLogItem = f.repeat(card, new Date(), Rating.Again, nextAfterHandler);\n * ```\n */\n next<R = RecordLogItem>(\n card: CardInput | Card,\n now: DateInput,\n grade: Grade,\n afterHandler?: (recordLog: RecordLogItem) => R\n ): R {\n const instance = this.getScheduler(card, now)\n const g = TypeConvert.rating(grade)\n if (g === Rating.Manual) {\n throw new Error('Cannot review a manual rating')\n }\n const recordLogItem = instance.review(g)\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLogItem)\n } else {\n return recordLogItem as R\n }\n }\n\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: true\n ): string\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format?: false\n ): number\n /**\n * Get the retrievability of the card\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param format default:true , Convert the result to another type. (Optional)\n * @returns The retrievability of the card,if format is true, the result is a string, otherwise it is a number\n */\n get_retrievability(\n card: CardInput | Card,\n now?: DateInput,\n format: boolean = true\n ): string | number {\n const processedCard = TypeConvert.card(card)\n now = now ? TypeConvert.time(now) : new Date()\n const t =\n processedCard.state !== State.New\n ? Math.max(date_diff(now, processedCard.last_review as Date, 'days'), 0)\n : 0\n const r =\n processedCard.state !== State.New\n ? this.forgetting_curve(t, +processedCard.stability.toFixed(8))\n : 0\n return format ? `${(r * 100).toFixed(2)}%` : r\n }\n\n rollback(card: CardInput | Card, log: ReviewLogInput): Card\n rollback<R>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler: (prevCard: Card) => R\n ): R\n /**\n *\n * @param card Card to be processed\n * @param log last review log\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now);\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now);\n * const { card, log } = repeatFormAfterHandler[Rating.Hard];\n * const rollbackFromAfterHandler = f.rollback(card, log);\n * ```\n *\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now, cardAfterHandler); //see method: createEmptyCard\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now, repeatAfterHandler); //see method: fsrs.repeat()\n * const { card, log } = repeatFormAfterHandler[Rating.Hard];\n * const rollbackFromAfterHandler = f.rollback(card, log, cardAfterHandler);\n * ```\n */\n rollback<R = Card>(\n card: CardInput | Card,\n log: ReviewLogInput,\n afterHandler?: (prevCard: Card) => R\n ): R {\n const processedCard = TypeConvert.card(card)\n const processedLog = TypeConvert.review_log(log)\n if (processedLog.rating === Rating.Manual) {\n throw new Error('Cannot rollback a manual rating')\n }\n let last_due: Date\n let last_review: Date | undefined\n let last_lapses: number\n switch (processedLog.state) {\n case State.New:\n last_due = processedLog.due\n last_review = undefined\n last_lapses = 0\n break\n case State.Learning:\n case State.Relearning:\n case State.Review:\n last_due = processedLog.review\n last_review = processedLog.due\n last_lapses =\n processedCard.lapses -\n (processedLog.rating === Rating.Again &&\n processedLog.state === State.Review\n ? 1\n : 0)\n break\n }\n\n const prevCard: Card = {\n ...processedCard,\n due: last_due,\n stability: processedLog.stability,\n difficulty: processedLog.difficulty,\n elapsed_days: processedLog.last_elapsed_days,\n scheduled_days: processedLog.scheduled_days,\n reps: Math.max(0, processedCard.reps - 1),\n lapses: Math.max(0, last_lapses),\n learning_steps: processedLog.learning_steps,\n state: processedLog.state,\n last_review: last_review,\n }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(prevCard)\n } else {\n return prevCard as R\n }\n }\n\n forget(\n card: CardInput | Card,\n now: DateInput,\n reset_count?: boolean\n ): RecordLogItem\n forget<R>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean | undefined,\n afterHandler: (recordLogItem: RecordLogItem) => R\n ): R\n /**\n *\n * @param card Card to be processed\n * @param now Current time or scheduled time\n * @param reset_count Should the review count information(reps,lapses) be reset. (Optional)\n * @param afterHandler Convert the result to another type. (Optional)\n * @example\n * ```typescript\n * const now = new Date();\n * const f = fsrs();\n * const emptyCard = createEmptyCard(now);\n * const scheduling_cards = f.repeat(emptyCard, now);\n * const { card, log } = scheduling_cards[Rating.Hard];\n * const forgetCard = f.forget(card, new Date(), true);\n * ```\n *\n * @example\n * ```typescript\n * interface RepeatRecordLog {\n * card: CardUnChecked; //see method: createEmptyCard\n * log: RevLogUnchecked; //see method: fsrs.repeat()\n * }\n *\n * function forgetAfterHandler(recordLogItem: RecordLogItem): RepeatRecordLog {\n * return {\n * card: {\n * ...(recordLogItem.card as Card & { cid: string }),\n * due: recordLogItem.card.due.getTime(),\n * state: State[recordLogItem.card.state] as StateType,\n * last_review: recordLogItem.card.last_review\n * ? recordLogItem.card.last_review!.getTime()\n * : null,\n * },\n * log: {\n * ...recordLogItem.log,\n * cid: (recordLogItem.card as Card & { cid: string }).cid,\n * due: recordLogItem.log.due.getTime(),\n * review: recordLogItem.log.review.getTime(),\n * state: State[recordLogItem.log.state] as StateType,\n * rating: Rating[recordLogItem.log.rating] as RatingType,\n * },\n * };\n * }\n * const now = new Date();\n * const f = fsrs();\n * const emptyCardFormAfterHandler = createEmptyCard(now, cardAfterHandler); //see method: createEmptyCard\n * const repeatFormAfterHandler = f.repeat(emptyCardFormAfterHandler, now, repeatAfterHandler); //see method: fsrs.repeat()\n * const { card } = repeatFormAfterHandler[Rating.Hard];\n * const forgetFromAfterHandler = f.forget(card, date_scheduler(now, 1, true), false, forgetAfterHandler);\n * ```\n */\n forget<R = RecordLogItem>(\n card: CardInput | Card,\n now: DateInput,\n reset_count: boolean = false,\n afterHandler?: (recordLogItem: RecordLogItem) => R\n ): R {\n const processedCard = TypeConvert.card(card)\n now = TypeConvert.time(now)\n const scheduled_days =\n processedCard.state === State.New\n ? 0\n : date_diff(now, processedCard.due as Date, 'days')\n const forget_log: ReviewLog = {\n rating: Rating.Manual,\n state: processedCard.state,\n due: processedCard.due,\n stability: processedCard.stability,\n difficulty: processedCard.difficulty,\n elapsed_days: 0,\n last_elapsed_days: processedCard.elapsed_days,\n scheduled_days: scheduled_days,\n learning_steps: processedCard.learning_steps,\n review: now,\n }\n const forget_card: Card = {\n ...processedCard,\n due: now,\n stability: 0,\n difficulty: 0,\n elapsed_days: 0,\n scheduled_days: 0,\n reps: reset_count ? 0 : processedCard.reps,\n lapses: reset_count ? 0 : processedCard.lapses,\n learning_steps: 0,\n state: State.New,\n last_review: processedCard.last_review,\n }\n const recordLogItem: RecordLogItem = { card: forget_card, log: forget_log }\n if (afterHandler && typeof afterHandler === 'function') {\n return afterHandler(recordLogItem)\n } else {\n return recordLogItem as R\n }\n }\n\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews: FSRSHistory[] | undefined,\n options: RequireOnly<RescheduleOptions<T>, 'recordLogHandler'>\n ): IReschedule<T>\n reschedule(\n current_card: CardInput | Card,\n reviews?: FSRSHistory[],\n options?: Partial<RescheduleOptions<RecordLogItem>>\n ): IReschedule<RecordLogItem>\n /**\n * Reschedules the current card and returns the rescheduled collections and reschedule item.\n *\n * @template T - The type of the record log item.\n * @param {CardInput | Card} current_card - The current card to be rescheduled.\n * @param {Array<FSRSHistory>} reviews - The array of FSRSHistory objects representing the reviews.\n * @param {Partial<RescheduleOptions<T>>} options - The optional reschedule options.\n * @returns {IReschedule<T>} - The rescheduled collections and reschedule item.\n *\n * @example\n * ```typescript\n * const f = fsrs()\n * const grades: Grade[] = [Rating.Good, Rating.Good, Rating.Good, Rating.Good]\n * const reviews_at = [\n * new Date(2024, 8, 13),\n * new Date(2024, 8, 13),\n * new Date(2024, 8, 17),\n * new Date(2024, 8, 28),\n * ]\n *\n * const reviews: FSRSHistory[] = []\n * for (let i = 0; i < grades.length; i++) {\n * reviews.push({\n * rating: grades[i],\n * review: reviews_at[i],\n * })\n * }\n *\n * const results_short = scheduler.reschedule(\n * createEmptyCard(),\n * reviews,\n * {\n * skipManual: false,\n * }\n * )\n * console.log(results_short)\n * ```\n */\n reschedule<T = RecordLogItem>(\n current_card: CardInput | Card,\n reviews: FSRSHistory[] = [],\n options: Partial<RescheduleOptions<T>> = {}\n ): IReschedule<T> {\n const {\n recordLogHandler,\n reviewsOrderBy,\n skipManual = true,\n now = new Date(),\n update_memory_state: updateMemoryState = false,\n } = options\n if (reviewsOrderBy && typeof reviewsOrderBy === 'function') {\n reviews.sort(reviewsOrderBy)\n }\n if (skipManual) {\n reviews = reviews.filter((review) => review.rating !== Rating.Manual)\n }\n const rescheduleSvc = new Reschedule(this)\n\n const collections = rescheduleSvc.reschedule(\n options.first_card || createEmptyCard(),\n reviews\n )\n const len = collections.length\n const cur_card = TypeConvert.card(current_card)\n const manual_item = rescheduleSvc.calculateManualRecord(\n cur_card,\n now,\n len ? collections[len - 1] : undefined,\n updateMemoryState\n )\n\n if (recordLogHandler && typeof recordLogHandler === 'function') {\n return {\n collections: collections.map(recordLogHandler),\n reschedule_item: manual_item ? recordLogHandler(manual_item) : null,\n }\n }\n return {\n collections,\n reschedule_item: manual_item,\n } as IReschedule<T>\n }\n}\n\n/**\n * Create a new instance of TS-FSRS\n * @param params FSRSParameters\n * @example\n * ```typescript\n * const f = fsrs();\n * ```\n * @example\n * ```typescript\n * const params: FSRSParameters = generatorParameters({ maximum_interval: 1000 });\n * const f = fsrs(params);\n * ```\n * @example\n * ```typescript\n * const f = fsrs({ maximum_interval: 1000 });\n * ```\n */\nexport const fsrs = (params?: Partial<FSRSParameters>) => {\n return new FSRS(params || {})\n}\n"],"names":["State","Rating","StrategyMode"],"mappings":"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"}