"use strict";var u=(r=>(r[r.New=0]="New",r[r.Learning=1]="Learning",r[r.Review=2]="Review",r[r.Relearning=3]="Relearning",r))(u||{}),l=(r=>(r[r.Manual=0]="Manual",r[r.Again=1]="Again",r[r.Hard=2]="Hard",r[r.Good=3]="Good",r[r.Easy=4]="Easy",r))(l||{});class h{static card(t){return{...t,state:h.state(t.state),due:h.time(t.due),last_review:t.last_review?h.time(t.last_review):void 0}}static rating(t){if(typeof t=="string"){const e=t.charAt(0).toUpperCase(),i=t.slice(1).toLowerCase(),a=l[`${e}${i}`];if(a===void 0)throw new Error(`Invalid rating:[${t}]`);return a}else if(typeof t=="number")return t;throw new Error(`Invalid rating:[${t}]`)}static state(t){if(typeof t=="string"){const e=t.charAt(0).toUpperCase(),i=t.slice(1).toLowerCase(),a=u[`${e}${i}`];if(a===void 0)throw new Error(`Invalid state:[${t}]`);return a}else if(typeof t=="number")return t;throw new Error(`Invalid state:[${t}]`)}static time(t){if(typeof t=="object"&&t instanceof Date)return t;if(typeof t=="string"){const e=Date.parse(t);if(isNaN(e))throw new Error(`Invalid date:[${t}]`);return new Date(e)}else if(typeof t=="number")return new Date(t);throw new Error(`Invalid date:[${t}]`)}static review_log(t){return{...t,due:h.time(t.due),rating:h.rating(t.rating),state:h.state(t.state),review:h.time(t.review)}}}const A=.9,F=36500,$=[.4072,1.1829,3.1262,15.4722,7.2102,.5316,1.0651,.0234,1.616,.1544,1.0824,1.9813,.0953,.2975,2.2042,.2407,2.9466,.5034,.6567],L=!1,D=!0,P="v4.4.3 using FSRS V5.0",b=r=>{let t=$;return r?.w&&(r.w.length===19?t=r?.w:r.w.length===17&&(t=r?.w.concat([0,0]),t[4]=+(t[5]*2+t[4]).toFixed(8),t[5]=+(Math.log(t[5]*3+1)/3).toFixed(8),console.debug("[FSRS V5]auto fill w to 19 length"))),{request_retention:r?.request_retention||A,maximum_interval:r?.maximum_interval||F,w:t,enable_fuzz:r?.enable_fuzz??L,enable_short_term:r?.enable_short_term??D}};function w(r,t){const e={due:r?h.time(r):new Date,stability:0,difficulty:0,elapsed_days:0,scheduled_days:0,reps:0,lapses:0,state:u.New,last_review:void 0};return t&&typeof t=="function"?t(e):e}Date.prototype.scheduler=function(r,t){return G(this,r,t)},Date.prototype.diff=function(r,t){return H(this,r,t)},Date.prototype.format=function(){return k(this)},Date.prototype.dueFormat=function(r,t,e){return z(this,r,t,e)};function G(r,t,e){return new Date(e?_(r).getTime()+t*24*60*60*1e3:_(r).getTime()+t*60*1e3)}function H(r,t,e){if(!r||!t)throw new Error("Invalid date");const i=_(r).getTime()-_(t).getTime();let a=0;switch(e){case"days":a=Math.floor(i/(24*60*60*1e3));break;case"minutes":a=Math.floor(i/(60*1e3));break}return a}function k(r){const t=_(r),e=t.getFullYear(),i=t.getMonth()+1,a=t.getDate(),s=t.getHours(),n=t.getMinutes(),d=t.getSeconds();return`${e}-${g(i)}-${g(a)} ${g(s)}:${g(n)}:${g(d)}`}function g(r){return r<10?`0${r}`:`${r}`}const M=[60,60,24,31,12],R=["second","min","hour","day","month","year"];function z(r,t,e,i=R){r=_(r),t=_(t),i.length!==R.length&&(i=R);let a=r.getTime()-t.getTime(),s;for(a/=1e3,s=0;st&&(a=Math.max(a,t+1)),a=Math.min(a,s),{min_ivl:a,max_ivl:s}}function p(r,t,e){return Math.min(Math.max(r,t),e)}class B{c;s0;s1;s2;constructor(t){const e=J();this.c=1,this.s0=e(" "),this.s1=e(" "),this.s2=e(" "),t==null&&(t=+new Date),this.s0-=e(t),this.s0<0&&(this.s0+=1),this.s1-=e(t),this.s1<0&&(this.s1+=1),this.s2-=e(t),this.s2<0&&(this.s2+=1)}next(){const t=2091639*this.s0+this.c*23283064365386963e-26;return this.s0=this.s1,this.s1=this.s2,this.s2=t-(this.c=t|0),this.s2}set state(t){this.c=t.c,this.s0=t.s0,this.s1=t.s1,this.s2=t.s2}get state(){return{c:this.c,s0:this.s0,s1:this.s1,s2:this.s2}}}function J(){let r=4022871197;return function(t){t=String(t);for(let e=0;e>>0,i-=r,i*=r,r=i>>>0,i-=r,r+=i*4294967296}return(r>>>0)*23283064365386963e-26}}function K(r){const t=new B(r),e=()=>t.next();return e.int32=()=>t.next()*4294967296|0,e.double=()=>e()+(e()*2097152|0)*11102230246251565e-32,e.state=()=>t.state,e.importState=i=>(t.state=i,e),e}const S=-.5,E=19/81;class q{param;intervalModifier;_seed;constructor(t){this.param=new Proxy(b(t),this.params_handler_proxy()),this.intervalModifier=this.calculate_interval_modifier(this.param.request_retention)}get interval_modifier(){return this.intervalModifier}set seed(t){this._seed=t}calculate_interval_modifier(t){if(t<=0||t>1)throw new Error("Requested retention rate should be in the range (0,1]");return+((Math.pow(t,1/S)-1)/E).toFixed(8)}get parameters(){return this.param}set parameters(t){this.update_parameters(t)}params_handler_proxy(){const t=this;return{set:function(e,i,a){return i==="request_retention"&&Number.isFinite(a)&&(t.intervalModifier=t.calculate_interval_modifier(Number(a))),Reflect.set(e,i,a),!0}}}update_parameters(t){const e=b(t);for(const i in e)if(i in this.param){const a=i;this.param[a]=e[a]}}init_stability(t){return Math.max(this.param.w[t-1],.1)}init_difficulty(t){return this.constrain_difficulty(this.param.w[4]-Math.exp((t-1)*this.param.w[5])+1)}apply_fuzz(t,e){if(!this.param.enable_fuzz||t<2.5)return Math.round(t);const i=K(this._seed)(),{min_ivl:a,max_ivl:s}=I(t,e,this.param.maximum_interval);return Math.floor(i*(s-a+1)+a)}next_interval(t,e){const i=Math.min(Math.max(1,Math.round(t*this.intervalModifier)),this.param.maximum_interval);return this.apply_fuzz(i,e)}next_difficulty(t,e){const i=t-this.param.w[6]*(e-3);return this.constrain_difficulty(this.mean_reversion(this.init_difficulty(l.Easy),i))}constrain_difficulty(t){return Math.min(Math.max(+t.toFixed(8),1),10)}mean_reversion(t,e){return+(this.param.w[7]*t+(1-this.param.w[7])*e).toFixed(8)}next_recall_stability(t,e,i,a){const s=l.Hard===a?this.param.w[15]:1,n=l.Easy===a?this.param.w[16]:1;return+p(e*(1+Math.exp(this.param.w[8])*(11-t)*Math.pow(e,-this.param.w[9])*(Math.exp((1-i)*this.param.w[10])-1)*s*n),.01,36500).toFixed(8)}next_forget_stability(t,e,i){return+p(this.param.w[11]*Math.pow(t,-this.param.w[12])*(Math.pow(e+1,this.param.w[13])-1)*Math.exp((1-i)*this.param.w[14]),.01,36500).toFixed(8)}next_short_term_stability(t,e){return+p(t*Math.exp(this.param.w[17]*(e-3+this.param.w[18])),.01,36500).toFixed(8)}forgetting_curve(t,e){return+Math.pow(1+E*t/e,S).toFixed(8)}}class C{last;current;review_time;next=new Map;algorithm;constructor(t,e,i){this.algorithm=i,this.last=h.card(t),this.current=h.card(t),this.review_time=h.time(e),this.init()}init(){const{state:t,last_review:e}=this.current;let i=0;t!==u.New&&e&&(i=this.review_time.diff(e,"days")),this.current.last_review=this.review_time,this.current.elapsed_days=i,this.current.reps+=1,this.initSeed()}preview(){return{[l.Again]:this.review(l.Again),[l.Hard]:this.review(l.Hard),[l.Good]:this.review(l.Good),[l.Easy]:this.review(l.Easy),[Symbol.iterator]:this.previewIterator.bind(this)}}*previewIterator(){for(const t of N)yield this.review(t)}review(t){const{state:e}=this.last;let i;switch(e){case u.New:i=this.newState(t);break;case u.Learning:case u.Relearning:i=this.learningState(t);break;case u.Review:i=this.reviewState(t);break}if(i)return i;throw new Error("Invalid grade")}initSeed(){const t=this.review_time.getTime(),e=this.current.reps,i=this.current.difficulty*this.current.stability;this.algorithm.seed=`${t}_${e}_${i}`}buildLog(t){const{last_review:e,due:i,elapsed_days:a}=this.last;return{rating:t,state:this.current.state,due:e||i,stability:this.current.stability,difficulty:this.current.difficulty,elapsed_days:this.current.elapsed_days,last_elapsed_days:a,scheduled_days:this.current.scheduled_days,review:this.review_time}}}class T extends C{newState(t){const e=this.next.get(t);if(e)return e;const i=h.card(this.current);switch(i.difficulty=this.algorithm.init_difficulty(t),i.stability=this.algorithm.init_stability(t),t){case l.Again:i.scheduled_days=0,i.due=this.review_time.scheduler(1),i.state=u.Learning;break;case l.Hard:i.scheduled_days=0,i.due=this.review_time.scheduler(5),i.state=u.Learning;break;case l.Good:i.scheduled_days=0,i.due=this.review_time.scheduler(10),i.state=u.Learning;break;case l.Easy:{const s=this.algorithm.next_interval(i.stability,this.current.elapsed_days);i.scheduled_days=s,i.due=this.review_time.scheduler(s,!0),i.state=u.Review;break}default:throw new Error("Invalid grade")}const a={card:i,log:this.buildLog(t)};return this.next.set(t,a),a}learningState(t){const e=this.next.get(t);if(e)return e;const{state:i,difficulty:a,stability:s}=this.last,n=h.card(this.current),d=this.current.elapsed_days;switch(n.difficulty=this.algorithm.next_difficulty(a,t),n.stability=this.algorithm.next_short_term_stability(s,t),t){case l.Again:{n.scheduled_days=0,n.due=this.review_time.scheduler(5,!1),n.state=i;break}case l.Hard:{n.scheduled_days=0,n.due=this.review_time.scheduler(10),n.state=i;break}case l.Good:{const c=this.algorithm.next_interval(n.stability,d);n.scheduled_days=c,n.due=this.review_time.scheduler(c,!0),n.state=u.Review;break}case l.Easy:{const c=this.algorithm.next_short_term_stability(s,l.Good),f=this.algorithm.next_interval(c,d),y=Math.max(this.algorithm.next_interval(n.stability,d),f+1);n.scheduled_days=y,n.due=this.review_time.scheduler(y,!0),n.state=u.Review;break}default:throw new Error("Invalid grade")}const o={card:n,log:this.buildLog(t)};return this.next.set(t,o),o}reviewState(t){const e=this.next.get(t);if(e)return e;const i=this.current.elapsed_days,{difficulty:a,stability:s}=this.last,n=this.algorithm.forgetting_curve(i,s),d=h.card(this.current),o=h.card(this.current),c=h.card(this.current),f=h.card(this.current);this.next_ds(d,o,c,f,a,s,n),this.next_interval(d,o,c,f,i),this.next_state(d,o,c,f),d.lapses+=1;const y={card:d,log:this.buildLog(l.Again)},v={card:o,log:super.buildLog(l.Hard)},m={card:c,log:super.buildLog(l.Good)},x={card:f,log:super.buildLog(l.Easy)};return this.next.set(l.Again,y),this.next.set(l.Hard,v),this.next.set(l.Good,m),this.next.set(l.Easy,x),this.next.get(t)}next_ds(t,e,i,a,s,n,d){t.difficulty=this.algorithm.next_difficulty(s,l.Again),t.stability=this.algorithm.next_forget_stability(s,n,d),e.difficulty=this.algorithm.next_difficulty(s,l.Hard),e.stability=this.algorithm.next_recall_stability(s,n,d,l.Hard),i.difficulty=this.algorithm.next_difficulty(s,l.Good),i.stability=this.algorithm.next_recall_stability(s,n,d,l.Good),a.difficulty=this.algorithm.next_difficulty(s,l.Easy),a.stability=this.algorithm.next_recall_stability(s,n,d,l.Easy)}next_interval(t,e,i,a,s){let n,d;n=this.algorithm.next_interval(e.stability,s),d=this.algorithm.next_interval(i.stability,s),n=Math.min(n,d),d=Math.max(d,n+1);const o=Math.max(this.algorithm.next_interval(a.stability,s),d+1);t.scheduled_days=0,t.due=this.review_time.scheduler(5),e.scheduled_days=n,e.due=this.review_time.scheduler(n,!0),i.scheduled_days=d,i.due=this.review_time.scheduler(d,!0),a.scheduled_days=o,a.due=this.review_time.scheduler(o,!0)}next_state(t,e,i,a){t.state=u.Relearning,e.state=u.Review,i.state=u.Review,a.state=u.Review}}class O extends C{newState(t){const e=this.next.get(t);if(e)return e;this.current.scheduled_days=0,this.current.elapsed_days=0;const i=h.card(this.current),a=h.card(this.current),s=h.card(this.current),n=h.card(this.current);this.init_ds(i,a,s,n);const d=0;return this.next_interval(i,a,s,n,d),this.next_state(i,a,s,n),this.update_next(i,a,s,n),this.next.get(t)}init_ds(t,e,i,a){t.difficulty=this.algorithm.init_difficulty(l.Again),t.stability=this.algorithm.init_stability(l.Again),e.difficulty=this.algorithm.init_difficulty(l.Hard),e.stability=this.algorithm.init_stability(l.Hard),i.difficulty=this.algorithm.init_difficulty(l.Good),i.stability=this.algorithm.init_stability(l.Good),a.difficulty=this.algorithm.init_difficulty(l.Easy),a.stability=this.algorithm.init_stability(l.Easy)}learningState(t){return this.reviewState(t)}reviewState(t){const e=this.next.get(t);if(e)return e;const i=this.current.elapsed_days,{difficulty:a,stability:s}=this.last,n=this.algorithm.forgetting_curve(i,s),d=h.card(this.current),o=h.card(this.current),c=h.card(this.current),f=h.card(this.current);return this.next_ds(d,o,c,f,a,s,n),this.next_interval(d,o,c,f,i),this.next_state(d,o,c,f),d.lapses+=1,this.update_next(d,o,c,f),this.next.get(t)}next_ds(t,e,i,a,s,n,d){t.difficulty=this.algorithm.next_difficulty(s,l.Again),t.stability=this.algorithm.next_forget_stability(s,n,d),e.difficulty=this.algorithm.next_difficulty(s,l.Hard),e.stability=this.algorithm.next_recall_stability(s,n,d,l.Hard),i.difficulty=this.algorithm.next_difficulty(s,l.Good),i.stability=this.algorithm.next_recall_stability(s,n,d,l.Good),a.difficulty=this.algorithm.next_difficulty(s,l.Easy),a.stability=this.algorithm.next_recall_stability(s,n,d,l.Easy)}next_interval(t,e,i,a,s){let n,d,o,c;n=this.algorithm.next_interval(t.stability,s),d=this.algorithm.next_interval(e.stability,s),o=this.algorithm.next_interval(i.stability,s),c=this.algorithm.next_interval(a.stability,s),n=Math.min(n,d),d=Math.max(d,n+1),o=Math.max(o,d+1),c=Math.max(c,o+1),t.scheduled_days=n,t.due=this.review_time.scheduler(n,!0),e.scheduled_days=d,e.due=this.review_time.scheduler(d,!0),i.scheduled_days=o,i.due=this.review_time.scheduler(o,!0),a.scheduled_days=c,a.due=this.review_time.scheduler(c,!0)}next_state(t,e,i,a){t.state=u.Review,e.state=u.Review,i.state=u.Review,a.state=u.Review}update_next(t,e,i,a){const s={card:t,log:this.buildLog(l.Again)},n={card:e,log:super.buildLog(l.Hard)},d={card:i,log:super.buildLog(l.Good)},o={card:a,log:super.buildLog(l.Easy)};this.next.set(l.Again,s),this.next.set(l.Hard,n),this.next.set(l.Good,d),this.next.set(l.Easy,o)}}class Q{fsrs;constructor(t){this.fsrs=t}replay(t,e,i){return this.fsrs.next(t,e,i)}handleManualRating(t,e,i,a,s,n,d){if(typeof e>"u")throw new Error("reschedule: state is required for manual rating");let o,c;if(e===u.New)o={rating:l.Manual,state:e,due:d??i,stability:t.stability,difficulty:t.difficulty,elapsed_days:a,last_elapsed_days:t.elapsed_days,scheduled_days:t.scheduled_days,review:i},c=w(i),c.last_review=i;else{if(typeof d>"u")throw new Error("reschedule: due is required for manual rating");const f=d.diff(i,"days");o={rating:l.Manual,state:t.state,due:t.last_review||t.due,stability:t.stability,difficulty:t.difficulty,elapsed_days:a,last_elapsed_days:t.elapsed_days,scheduled_days:t.scheduled_days,review:i},c={...t,state:e,due:d,last_review:i,stability:s||t.stability,difficulty:n||t.difficulty,elapsed_days:a,scheduled_days:f,reps:t.reps+1}}return{card:c,log:o}}reschedule(t,e){const i=[];let a=w(t.due);for(const s of e){let n;if(s.review=h.time(s.review),s.rating===l.Manual){let d=0;a.state!==u.New&&a.last_review&&(d=s.review.diff(a.last_review,"days")),n=this.handleManualRating(a,s.state,s.review,d,s.stability,s.difficulty,s.due?h.time(s.due):void 0)}else n=this.replay(a,s.review,s.rating);i.push(n),a=n.card}return i}calculateManualRecord(t,e,i,a){if(!i)return null;const{card:s,log:n}=i,d=h.card(t);return d.due.getTime()===s.due.getTime()?null:(d.scheduled_days=s.due.diff(d.due,"days"),this.handleManualRating(d,s.state,h.time(e),n.elapsed_days,a?s.stability:void 0,a?s.difficulty:void 0,s.due))}}class V extends q{Scheduler;constructor(t){super(t);const{enable_short_term:e}=this.parameters;this.Scheduler=e?T:O}params_handler_proxy(){const t=this;return{set:function(e,i,a){return i==="request_retention"&&Number.isFinite(a)?t.intervalModifier=t.calculate_interval_modifier(Number(a)):i==="enable_short_term"&&(t.Scheduler=a===!0?T:O),Reflect.set(e,i,a),!0}}}repeat(t,e,i){const a=this.Scheduler,s=new a(t,e,this).preview();return i&&typeof i=="function"?i(s):s}next(t,e,i,a){const s=this.Scheduler,n=new s(t,e,this),d=h.rating(i);if(d===l.Manual)throw new Error("Cannot review a manual rating");const o=n.review(d);return a&&typeof a=="function"?a(o):o}get_retrievability(t,e,i=!0){const a=h.card(t);e=e?h.time(e):new Date;const s=a.state!==u.New?Math.max(e.diff(a.last_review,"days"),0):0,n=a.state!==u.New?this.forgetting_curve(s,+a.stability.toFixed(8)):0;return i?`${(n*100).toFixed(2)}%`:n}rollback(t,e,i){const a=h.card(t),s=h.review_log(e);if(s.rating===l.Manual)throw new Error("Cannot rollback a manual rating");let n,d,o;switch(s.state){case u.New:n=s.due,d=void 0,o=0;break;case u.Learning:case u.Relearning:case u.Review:n=s.review,d=s.due,o=a.lapses-(s.rating===l.Again&&s.state===u.Review?1:0);break}const c={...a,due:n,stability:s.stability,difficulty:s.difficulty,elapsed_days:s.last_elapsed_days,scheduled_days:s.scheduled_days,reps:Math.max(0,a.reps-1),lapses:Math.max(0,o),state:s.state,last_review:d};return i&&typeof i=="function"?i(c):c}forget(t,e,i=!1,a){const s=h.card(t);e=h.time(e);const n=s.state===u.New?0:e.diff(s.last_review,"days"),d={rating:l.Manual,state:s.state,due:s.due,stability:s.stability,difficulty:s.difficulty,elapsed_days:0,last_elapsed_days:s.elapsed_days,scheduled_days:n,review:e},o={card:{...s,due:e,stability:0,difficulty:0,elapsed_days:0,scheduled_days:0,reps:i?0:s.reps,lapses:i?0:s.lapses,state:u.New,last_review:s.last_review},log:d};return a&&typeof a=="function"?a(o):o}reschedule(t,e=[],i={}){const{recordLogHandler:a,reviewsOrderBy:s,skipManual:n=!0,now:d=new Date,update_memory_state:o=!1}=i;s&&typeof s=="function"&&e.sort(s),n&&(e=e.filter(x=>x.rating!==l.Manual));const c=new Q(this),f=c.reschedule(i.first_card||w(),e),y=f.length,v=h.card(t),m=c.calculateManualRecord(v,d,y?f[y-1]:void 0,o);return a&&typeof a=="function"?{collections:f.map(a),reschedule_item:m?a(m):null}:{collections:f,reschedule_item:m}}}const W=r=>new V(r||{});exports.DECAY=S,exports.FACTOR=E,exports.FSRS=V,exports.FSRSAlgorithm=q,exports.FSRSVersion=P,exports.Grades=N,exports.Rating=l,exports.State=u,exports.TypeConvert=h,exports.clamp=p,exports.createEmptyCard=w,exports.date_diff=H,exports.date_scheduler=G,exports.default_enable_fuzz=L,exports.default_enable_short_term=D,exports.default_maximum_interval=F,exports.default_request_retention=A,exports.default_w=$,exports.fixDate=_,exports.fixRating=j,exports.fixState=Y,exports.formatDate=k,exports.fsrs=W,exports.generatorParameters=b,exports.get_fuzz_range=I,exports.show_diff_message=z,module.exports=Object.assign(exports.default||{},exports); //# sourceMappingURL=index.cjs.map