您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Additional statistics filters for the WaniKani Open Framework
当前为
// ==UserScript== // @name WaniKani Open Framework Statistics Filters // @namespace https://www.wanikani.com // @description Additional statistics filters for the WaniKani Open Framework // @author prouleau // @version 1.1.0 // @include https://www.wanikani.com/* // @grant none // ==/UserScript== (function(wkof) { 'use strict'; var wkofMinimumVersion = '1.0.52'; if (!wkof) { var response = confirm('WaniKani Open Framework Date Filters requires WaniKani Open Framework.\n Click "OK" to be forwarded to installation instructions.'); if (response) { window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549'; } return; } var settingsDialog; var settingsScriptId = 'statsFilters'; var settingsTitle = 'Statistics Filters'; var needToRegisterFilters = true; var filterNamePrefix = 'statsFilters_'; var leechLteqFilterName = filterNamePrefix + 'LeechLteq'; var meaningCorAnsLteqFilterName = filterNamePrefix + 'meaningCorAnsLteq'; var meaningCorAnsGteqFilterName = filterNamePrefix + 'meaningCorAnsGteq'; var readingCorAnsLteqFilterName = filterNamePrefix + 'readingCorAnsLteq'; var readingCorAnsGteqFilterName = filterNamePrefix + 'readingCorAnsGteq'; var meaningIncorAnsLteqFilterName = filterNamePrefix + 'meaningIncorAnsLteq'; var meaningIncorAnsGteqFilterName = filterNamePrefix + 'meaningIncorAnsGteq'; var readingIncorAnsLteqFilterName = filterNamePrefix + 'readingIncorAnsLteq'; var readingIncorAnsGteqFilterName = filterNamePrefix + 'readingIncorAnsGteq'; var totalCorAnsLteqFilterName = filterNamePrefix + 'totalCorAnsLteq'; var totalCorAnsGteqFilterName = filterNamePrefix + 'totalCorAnsGteq'; var totalIncorAnsLteqFilterName = filterNamePrefix + 'totalIncorAnsLteq'; var totalIncorAnsGteqFilterName = filterNamePrefix + 'totalIncorAnsGteq'; var percentageTotalCorLteqFilterName = filterNamePrefix + 'percentageTotalCorLteq'; var percentageTotalCorGteqFilterName = filterNamePrefix + 'percentageTotalCorGteq'; var percentageMeaningCorLteqFilterName = filterNamePrefix + 'pecentagerMeaningCorLteq'; var percentageMeaningCorGteqFilterName = filterNamePrefix + 'percentageMeaningCorGteq'; var percentageReadingCorLteqFilterName = filterNamePrefix + 'percentageReadingCorLteq'; var percentageReadingCorGteqFilterName = filterNamePrefix + 'percentageReadingCorGteq'; var meaningCurStrLteqFilterName = filterNamePrefix + 'meaningCurStrLteq'; var meaningCurStrGteqFilterName = filterNamePrefix + 'meaningCurStrGteq'; var meaningMaxStrLteqFilterName = filterNamePrefix + 'meaningMaxStrLteq'; var meaningMaxStrGteqFilterName = filterNamePrefix + 'meaningMaxStrGteq'; var readingCurStrLteqFilterName = filterNamePrefix + 'readingCurStrLteq'; var readingCurStrGteqFilterName = filterNamePrefix + 'readingCurStrGteq'; var readingMaxStrLteqFilterName = filterNamePrefix + 'readingMaxStrLteq'; var readingMaxStrGteqFilterName = filterNamePrefix + 'readingMaxStrGteq'; var bothCurStrLteqFilterName = filterNamePrefix + 'bothCurStrLteq'; var bothCurStrGteqFilterName = filterNamePrefix + 'bothCurStrGteq'; var minCurStrLteqFilterName = filterNamePrefix + 'minCurStrLteq'; var minCurStrGteqFilterName = filterNamePrefix + 'minCurStrGteq'; var supportedFilters = [leechLteqFilterName, meaningCorAnsLteqFilterName, meaningCorAnsGteqFilterName, readingCorAnsLteqFilterName, readingCorAnsGteqFilterName, meaningIncorAnsLteqFilterName, meaningIncorAnsGteqFilterName, readingIncorAnsLteqFilterName, readingIncorAnsGteqFilterName, totalCorAnsLteqFilterName, totalCorAnsGteqFilterName, totalIncorAnsLteqFilterName, totalIncorAnsGteqFilterName, percentageTotalCorLteqFilterName, percentageTotalCorGteqFilterName, percentageMeaningCorLteqFilterName, percentageMeaningCorGteqFilterName, percentageReadingCorLteqFilterName, percentageReadingCorGteqFilterName, meaningCurStrLteqFilterName, meaningCurStrGteqFilterName, meaningMaxStrLteqFilterName, meaningMaxStrGteqFilterName, readingCurStrLteqFilterName, readingCurStrGteqFilterName, readingMaxStrLteqFilterName, readingMaxStrGteqFilterName, bothCurStrLteqFilterName, bothCurStrGteqFilterName, minCurStrLteqFilterName, minCurStrGteqFilterName,]; function updateFiltersWhenReady() { needToRegisterFilters = true; waitForItemDataRegistry().then(registerFilters); } function waitForItemDataRegistry() { return wkof.wait_state('wkof.ItemData.registry', 'ready'); } function registerFilters() { if (!needToRegisterFilters) { return; } supportedFilters.forEach(function(filterName) { delete wkof.ItemData.registry.sources.wk_items.filters[filterName]; }); registerLeechLteqFilter(); registerMeaningCorAnsGteqFilter(); registerMeaningCorAnsLteqFilter(); registerReadingCorAnsGteqFilter(); registerReadingCorAnsLteqFilter(); registerMeaningIncorAnsGteqFilter(); registerMeaningIncorAnsLteqFilter(); registerReadingIncorAnsGteqFilter(); registerReadingIncorAnsLteqFilter(); registerTotalCorAnsGteqFilter(); registerTotalCorAnsLteqFilter(); registerTotalIncorAnsGteqFilter(); registerTotalIncorAnsLteqFilter(); registerPercentageTotalCorGteqFilter(); registerPercentageTotalCorLteqFilter(); registerPercentageMeaningCorGteqFilter(); registerPercentageMeaningCorLteqFilter(); registerPercentageReadingCorGteqFilter(); registerPercentageReadingCorLteqFilter(); registerMeaningCurStrGteqFilter(); registerMeaningCurStrLteqFilter(); registerMeaningMaxStrGteqFilter(); registerMeaningMaxStrLteqFilter(); registerReadingCurStrGteqFilter(); registerReadingCurStrLteqFilter(); registerReadingMaxStrGteqFilter(); registerReadingMaxStrLteqFilter(); registerBothCurStrGteqFilter(); registerBothCurStrLteqFilter(); registerMinCurStrGteqFilter(); registerMinCurStrLteqFilter(); needToRegisterFilters = false; } // BEGIN Leech let leechLteqHover_tip = 'Select items that have a leech value less than or equal to the stated value.'; function registerLeechLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[leechLteqFilterName] = { type: 'number', label: 'Leech value <=', default: 10, filter_func: leechLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: leechLteqHover_tip, }; } function leechLteqFilter(filterValue, item) { if (item.review_statistics === undefined) { return false; } var reviewStats = item.review_statistics; var meaningScore = getLeechScore(reviewStats.meaning_incorrect, reviewStats.meaning_current_streak); var readingScore = getLeechScore(reviewStats.reading_incorrect, reviewStats.reading_current_streak); return meaningScore <= filterValue && readingScore <= filterValue; } // Leech scores a rounded because otherwise the behavior of the filter is not consistent with rounded values presented to users in scripts. // In other words, data would be not filtered when based on user facing data it appears that it should be. function getLeechScore(incorrect, currentStreak) { return Math.round((incorrect / Math.pow((currentStreak || 0.5), 1.5)) * 100) / 100; } // END Leech // BEGIN Meaning correct answers let meaningCorAnsGteqFilterHover_tip = 'Selects items where the number of correct\nanswers for Meaning is >= this value.'; let meaningCorAnsLteqFilterHover_tip = 'Selects items where the number of correct\nanswers for Meaning is <= this value.'; function registerMeaningCorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningCorAnsGteqFilterName] = { type: 'number', label: 'Meaning Cor. Ans. >=', default: 0, filter_func: meaningCorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningCorAnsGteqFilterHover_tip, }; } function meaningCorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_correct >= filterValue; } function registerMeaningCorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningCorAnsLteqFilterName] = { type: 'number', label: 'Meaning Cor. Ans. <=', default: 100, filter_func: meaningCorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningCorAnsLteqFilterHover_tip, }; } function meaningCorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_correct <= filterValue; } // END Meaning correct answers // BEGIN Reading correct answers let readingCorAnsGteqFilterHover_tip = 'Selects items where the number of correct\nanswers for Reading is >= this value.'; let readingCorAnsLteqFilterHover_tip = 'Selects items where the number of correct\nanswers for Reading is <= this value.'; function registerReadingCorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingCorAnsGteqFilterName] = { type: 'number', label: 'Reading Cor. Ans. >=', default: 0, filter_func: readingCorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingCorAnsGteqFilterHover_tip, }; } function readingCorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_correct >= filterValue; } function registerReadingCorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingCorAnsLteqFilterName] = { type: 'number', label: 'Reading Cor. Ans. <=', default: 100, filter_func: readingCorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingCorAnsLteqFilterHover_tip, }; } function readingCorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_correct <= filterValue; } // END Reading correct answers // BEGIN Meaning incorrect answers let meaningIncorAnsGteqFilterHover_tip = 'Selects items where the number of incorrect\nanswers for Meaning is >= this value.'; let meaningIncorAnsLteqFilterHover_tip = 'Selects items where the number of incorrect\nanswers for Meaning is <= this value.'; function registerMeaningIncorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningIncorAnsGteqFilterName] = { type: 'number', label: 'Meaning Incor. Ans. >=', default: 0, filter_func: meaningIncorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningIncorAnsGteqFilterHover_tip, }; } function meaningIncorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_incorrect >= filterValue; } function registerMeaningIncorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningIncorAnsLteqFilterName] = { type: 'number', label: 'Meaning Incor. Ans. <=', default: 100, filter_func: meaningIncorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningIncorAnsLteqFilterHover_tip, }; } function meaningIncorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_incorrect <= filterValue; } // END Meaning incorrect answers // BEGIN Reading incorrect answers let readingIncorAnsGteqFilterHover_tip = 'Selects items where the number of incorrect\nanswers for Reading is >= this value.'; let readingIncorAnsLteqFilterHover_tip = 'Selects items where the number of incorrect\nanswers for Reading is <= this value.'; function registerReadingIncorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingIncorAnsGteqFilterName] = { type: 'number', label: 'Reading Incor. Ans. >=', default: 0, filter_func: readingIncorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingIncorAnsGteqFilterHover_tip, }; } function readingIncorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_incorrect >= filterValue; } function registerReadingIncorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingIncorAnsLteqFilterName] = { type: 'number', label: 'Reading Incor. Ans. <=', default: 100, filter_func: readingIncorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingIncorAnsLteqFilterHover_tip, }; } function readingIncorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_incorrect <= filterValue; } // END Reading incorrect answers // BEGIN Total correct answers let totalCorAnsGteqFilterHover_tip = 'Selects items where the total number\nof correct answers is >= this value.'; let totalCorAnsLteqFilterHover_tip = 'Selects items where the total number\nof correct answers is <= this value.'; function registerTotalCorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[totalCorAnsGteqFilterName] = { type: 'number', label: 'Total Cor. Ans. >=', default: 0, filter_func: totalCorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: totalCorAnsGteqFilterHover_tip, }; } function totalCorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_correct >= filterValue; } return review_statistics.meaning_correct + review_statistics.reading_correct >= filterValue; } function registerTotalCorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[totalCorAnsLteqFilterName] = { type: 'number', label: 'Total Cor. Ans. <=', default: 100, filter_func: totalCorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: totalCorAnsLteqFilterHover_tip, }; } function totalCorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_correct <= filterValue; } return review_statistics.meaning_correct + review_statistics.reading_correct <= filterValue; } // END Total correct answers // BEGIN Total incorrect answers let totalIncorAnsGteqFilterHover_tip = 'Selects items where the total number\nof incorrect answers is >= this value.'; let totalIncorAnsLteqFilterHover_tip = 'Selects items where the total number\nof incorrect answers is <= this value.'; function registerTotalIncorAnsGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[totalIncorAnsGteqFilterName] = { type: 'number', label: 'Total Incor. Ans. >=', default: 0, filter_func: totalIncorAnsGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: totalIncorAnsGteqFilterHover_tip, }; } function totalIncorAnsGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_incorrect >= filterValue; } return review_statistics.meaning_incorrect + review_statistics.reading_incorrect >= filterValue; } function registerTotalIncorAnsLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[totalIncorAnsLteqFilterName] = { type: 'number', label: 'Total Incor. Ans. <=', default: 100, filter_func: totalIncorAnsLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: totalIncorAnsLteqFilterHover_tip, }; } function totalIncorAnsLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_incorrect <= filterValue; } return review_statistics.meaning_incorrect + review_statistics.reading_incorrect <= filterValue; } // END Total incorrect answers //============================================== // Percentages filters // // Needs rounding because otherwise user facing data is usually floored and inconsistencies in displayed data will occur // Flooring is used instead of rounding because otherwise we could have 100% correct while missing some answers due to rounding function percentageRounding(value){return Math.floor(value * 100)}; // BEGIN Percentage Total Correct let percentageTotalCorGteqFilterHover_tip = 'Selects items where % of correct answers\non Total is >= this value.'; let percentageTotalCorLteqFilterHover_tip = 'Selects items where % of correct answers\non Total is <= this value.'; function registerPercentageTotalCorGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageTotalCorGteqFilterName] = { type: 'number', label: '%Total Correct >=', default: 0, filter_func: percentageTotalCorGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageTotalCorGteqFilterHover_tip, }; } function percentageTotalCorGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.percentage_correct >= filterValue; } function registerPercentageTotalCorLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageTotalCorLteqFilterName] = { type: 'number', label: '%Total Correct <=', default: 100, filter_func: percentageTotalCorLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageTotalCorLteqFilterHover_tip, }; } function percentageTotalCorLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.percentage_correct <= filterValue; } // END Percentage Total Correct // BEGIN Percentage Meaning Correct let percentageMeaningCorGteqFilterHover_tip = 'Selects items where % of correct answers\non Meaning is >= this value.'; let percentageMeaningCorLteqFilterHover_tip = 'Selects items where % of correct answers\non Meaning is <= this value.'; function registerPercentageMeaningCorGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageMeaningCorGteqFilterName] = { type: 'number', label: '%Meaning Correct >=', default: 0, filter_func: percentageMeaningCorGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageMeaningCorGteqFilterHover_tip, }; } function percentageMeaningCorGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return percentageRounding(review_statistics.meaning_correct / (review_statistics.meaning_correct + review_statistics.meaning_incorrect)) >= filterValue; } function registerPercentageMeaningCorLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageMeaningCorLteqFilterName] = { type: 'number', label: '%Meaning Correct <=', default: 100, filter_func: percentageMeaningCorLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageMeaningCorLteqFilterHover_tip, }; } function percentageMeaningCorLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return percentageRounding(review_statistics.meaning_correct / (review_statistics.meaning_correct + review_statistics.meaning_incorrect)) <= filterValue; } // END Percentage Meaning Correct // BEGIN Percentage Reading Correct let percentageReadingCorGteqFilterHover_tip = 'Selects items where % of correct answers\non Reading is >= this value.'; let percentageReadingCorLteqFilterHover_tip = 'Selects items where % of correct answers\non Reading is <= this value.'; function registerPercentageReadingCorGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageReadingCorGteqFilterName] = { type: 'number', label: '%Reading Correct >=', default: 0, filter_func: percentageReadingCorGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageReadingCorGteqFilterHover_tip, }; } function percentageReadingCorGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return percentageRounding(review_statistics.reading_correct / (review_statistics.reading_correct + review_statistics.reading_incorrect)) >= filterValue; } function registerPercentageReadingCorLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[percentageReadingCorLteqFilterName] = { type: 'number', label: '%Reading Correct <=', default: 100, filter_func: percentageReadingCorLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: percentageReadingCorLteqFilterHover_tip, }; } function percentageReadingCorLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return percentageRounding(review_statistics.reading_correct / (review_statistics.reading_correct + review_statistics.reading_incorrect)) <= filterValue; } // END Percentage Reading Correct //====================================================== // Streak Filters // // Wanikani starts the streak count at 1, that is when the last review is failed, the streak is 1, not 0. // User facing data is adjusted in Item Inspector to start the streak count at 0 because starting at 1 is not intuitive. // The filters do so too because the filter value in the settings panel is also user facing data that may be correlated with Item Inspector data. // This is done by adjusting the filter value through passing streakValueAdjustment to the filter_value_map: registering option. // This adjustment is not made in leech calculations because a- this use of streaks is not user facing data - and b- there is an history of // calculating leech values this way and it would be disruptive to change it. function streakValueAdjustment(param){return param + 1}; // BEGIN Meaning Current Streak let meaningCurStrGteqFilterHover_tip = 'Selects items where current Meaning streak is >= this value.'; let meaningCurStrLteqFilterHover_tip = 'Selects items where current Meaning streak is <= this value.'; function registerMeaningCurStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningCurStrGteqFilterName] = { type: 'number', label: 'Meaning Cur. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: meaningCurStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningCurStrGteqFilterHover_tip, }; } function meaningCurStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_current_streak >= filterValue; } function registerMeaningCurStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningCurStrLteqFilterName] = { type: 'number', label: 'Meaning Cur. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: meaningCurStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningCurStrLteqFilterHover_tip, }; } function meaningCurStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_current_streak <= filterValue; } // END Meaning Current Streak // BEGIN Meaning Maximum Streak let meaningMaxStrGteqFilterHover_tip = 'Selects items where maximum Meaning streak is >= this value.'; let meaningMaxStrLteqFilterHover_tip = 'Selects items where maximum Meaning streak is <= this value.'; function registerMeaningMaxStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningMaxStrGteqFilterName] = { type: 'number', label: 'Meaning Max. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: meaningMaxStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningMaxStrGteqFilterHover_tip, }; } function meaningMaxStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_max_streak >= filterValue; } function registerMeaningMaxStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[meaningMaxStrLteqFilterName] = { type: 'number', label: 'Meaning Max. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: meaningMaxStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: meaningMaxStrLteqFilterHover_tip, }; } function meaningMaxStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } return review_statistics.meaning_max_streak <= filterValue; } // END Meaning Maximum Streak // BEGIN Reading Current Streak let readingCurStrGteqFilterHover_tip = 'Selects items where current Reading streak is >= this value.'; let readingCurStrLteqFilterHover_tip = 'Selects items where current Reading streak is <= this value.'; function registerReadingCurStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingCurStrGteqFilterName] = { type: 'number', label: 'Reading Cur. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: readingCurStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingCurStrGteqFilterHover_tip, }; } function readingCurStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_current_streak >= filterValue; } function registerReadingCurStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingCurStrLteqFilterName] = { type: 'number', label: 'Reading Cur. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: readingCurStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingCurStrLteqFilterHover_tip, }; } function readingCurStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_current_streak <= filterValue; } // END Reading Current Streak // BEGIN Reading Maximum Streak let readingMaxStrGteqFilterHover_tip = 'Selects items where maximum Reading streak is >= this value.'; let readingMaxStrLteqFilterHover_tip = 'Selects items where maximum Reading streak is <= this value.'; function registerReadingMaxStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingMaxStrGteqFilterName] = { type: 'number', label: 'Reading Max. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: readingMaxStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingMaxStrGteqFilterHover_tip, }; } function readingMaxStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_max_streak >= filterValue; } function registerReadingMaxStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[readingMaxStrLteqFilterName] = { type: 'number', label: 'Reading Max. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: readingMaxStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: readingMaxStrLteqFilterHover_tip, }; } function readingMaxStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return false; } return review_statistics.reading_max_streak <= filterValue; } // END Reading Maximum Streak // BEGIN Both Current Streaks let bothCurStrGteqFilterHover_tip = 'Selects items where both current Meaning streak\nand current Reading streak are >= this value.'; let bothCurStrLteqFilterHover_tip = 'Selects items where both current Meaning streak\nand current Reading streak are <= this value.'; function registerBothCurStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[bothCurStrGteqFilterName] = { type: 'number', label: 'Both Cur. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: bothCurStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: bothCurStrGteqFilterHover_tip, }; } function bothCurStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_current_streak >= filterValue; } else { return review_statistics.meaning_current_streak >= filterValue && review_statistics.reading_current_streak >= filterValue; } } function registerBothCurStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[bothCurStrLteqFilterName] = { type: 'number', label: 'Both Cur. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: bothCurStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: bothCurStrLteqFilterHover_tip, }; } function bothCurStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_current_streak <= filterValue; } else { return review_statistics.meaning_current_streak <= filterValue && review_statistics.reading_current_streak <= filterValue; } } // END Both Current Streaks // BEGIN Both Current Streaks let minCurStrGteqFilterHover_tip = 'Selects items where the minimum of current Meaning streak\nand current Reading streak is >= this value.'; let minCurStrLteqFilterHover_tip = 'Selects items where the minimum of current Meaning streak\nand current Reading streak is <= this value.'; function registerMinCurStrGteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[minCurStrGteqFilterName] = { type: 'number', label: 'Minimum Cur. Str. >=', default: 0, filter_value_map: streakValueAdjustment, filter_func: minCurStrGteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: minCurStrGteqFilterHover_tip, }; } function minCurStrGteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_current_streak >= filterValue; } else { return review_statistics.meaning_current_streak >= filterValue && review_statistics.reading_current_streak >= filterValue; }; } function registerMinCurStrLteqFilter() { wkof.ItemData.registry.sources.wk_items.filters[minCurStrLteqFilterName] = { type: 'number', label: 'Minimum Cur. Str. <=', default: 100, filter_value_map: streakValueAdjustment, filter_func: minCurStrLteqFilter, set_options: function(options) { options.review_statistics = true; }, hover_tip: minCurStrLteqFilterHover_tip, }; } function minCurStrLteqFilter(filterValue, item) { let review_statistics = item.review_statistics; if (review_statistics === undefined) { return false; } if (item.object === 'radical'){ return review_statistics.meaning_current_streak <= filterValue; } else { return review_statistics.meaning_current_streak <= filterValue || review_statistics.reading_current_streak <= filterValue; } } // END Both Current Streaks updateFiltersWhenReady(); })(window.wkof);