var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to2, from2, except, desc) => { if (from2 && typeof from2 === "object" || typeof from2 === "function") { for (let key of __getOwnPropNames(from2)) if (!__hasOwnProp.call(to2, key) && key !== except) __defProp(to2, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); } return to2; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); // node_modules/.pnpm/moment@2.30.1/node_modules/moment/moment.js var require_moment = __commonJS({ "node_modules/.pnpm/moment@2.30.1/node_modules/moment/moment.js"(exports, module2) { (function(global, factory) { typeof exports === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.moment = factory(); })(exports, function() { "use strict"; var hookCallback; function hooks() { return hookCallback.apply(null, arguments); } function setHookCallback(callback2) { hookCallback = callback2; } function isArray2(input) { return input instanceof Array || Object.prototype.toString.call(input) === "[object Array]"; } function isObject2(input) { return input != null && Object.prototype.toString.call(input) === "[object Object]"; } function hasOwnProp(a2, b2) { return Object.prototype.hasOwnProperty.call(a2, b2); } function isObjectEmpty(obj) { if (Object.getOwnPropertyNames) { return Object.getOwnPropertyNames(obj).length === 0; } else { var k; for (k in obj) { if (hasOwnProp(obj, k)) { return false; } } return true; } } function isUndefined(input) { return input === void 0; } function isNumber2(input) { return typeof input === "number" || Object.prototype.toString.call(input) === "[object Number]"; } function isDate(input) { return input instanceof Date || Object.prototype.toString.call(input) === "[object Date]"; } function map3(arr, fn2) { var res = [], i2, arrLen = arr.length; for (i2 = 0; i2 < arrLen; ++i2) { res.push(fn2(arr[i2], i2)); } return res; } function extend(a2, b2) { for (var i2 in b2) { if (hasOwnProp(b2, i2)) { a2[i2] = b2[i2]; } } if (hasOwnProp(b2, "toString")) { a2.toString = b2.toString; } if (hasOwnProp(b2, "valueOf")) { a2.valueOf = b2.valueOf; } return a2; } function createUTC(input, format2, locale3, strict) { return createLocalOrUTC(input, format2, locale3, strict, true).utc(); } function defaultParsingFlags() { return { empty: false, unusedTokens: [], unusedInput: [], overflow: -2, charsLeftOver: 0, nullInput: false, invalidEra: null, invalidMonth: null, invalidFormat: false, userInvalidated: false, iso: false, parsedDateParts: [], era: null, meridiem: null, rfc2822: false, weekdayMismatch: false }; } function getParsingFlags(m2) { if (m2._pf == null) { m2._pf = defaultParsingFlags(); } return m2._pf; } var some; if (Array.prototype.some) { some = Array.prototype.some; } else { some = function(fun) { var t3 = Object(this), len = t3.length >>> 0, i2; for (i2 = 0; i2 < len; i2++) { if (i2 in t3 && fun.call(this, t3[i2], i2, t3)) { return true; } } return false; }; } function isValid(m2) { var flags = null, parsedParts = false, isNowValid = m2._d && !isNaN(m2._d.getTime()); if (isNowValid) { flags = getParsingFlags(m2); parsedParts = some.call(flags.parsedDateParts, function(i2) { return i2 != null; }); isNowValid = flags.overflow < 0 && !flags.empty && !flags.invalidEra && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || flags.meridiem && parsedParts); if (m2._strict) { isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === void 0; } } if (Object.isFrozen == null || !Object.isFrozen(m2)) { m2._isValid = isNowValid; } else { return isNowValid; } return m2._isValid; } function createInvalid(flags) { var m2 = createUTC(NaN); if (flags != null) { extend(getParsingFlags(m2), flags); } else { getParsingFlags(m2).userInvalidated = true; } return m2; } var momentProperties = hooks.momentProperties = [], updateInProgress = false; function copyConfig(to3, from3) { var i2, prop, val, momentPropertiesLen = momentProperties.length; if (!isUndefined(from3._isAMomentObject)) { to3._isAMomentObject = from3._isAMomentObject; } if (!isUndefined(from3._i)) { to3._i = from3._i; } if (!isUndefined(from3._f)) { to3._f = from3._f; } if (!isUndefined(from3._l)) { to3._l = from3._l; } if (!isUndefined(from3._strict)) { to3._strict = from3._strict; } if (!isUndefined(from3._tzm)) { to3._tzm = from3._tzm; } if (!isUndefined(from3._isUTC)) { to3._isUTC = from3._isUTC; } if (!isUndefined(from3._offset)) { to3._offset = from3._offset; } if (!isUndefined(from3._pf)) { to3._pf = getParsingFlags(from3); } if (!isUndefined(from3._locale)) { to3._locale = from3._locale; } if (momentPropertiesLen > 0) { for (i2 = 0; i2 < momentPropertiesLen; i2++) { prop = momentProperties[i2]; val = from3[prop]; if (!isUndefined(val)) { to3[prop] = val; } } } return to3; } function Moment3(config) { copyConfig(this, config); this._d = new Date(config._d != null ? config._d.getTime() : NaN); if (!this.isValid()) { this._d = /* @__PURE__ */ new Date(NaN); } if (updateInProgress === false) { updateInProgress = true; hooks.updateOffset(this); updateInProgress = false; } } function isMoment(obj) { return obj instanceof Moment3 || obj != null && obj._isAMomentObject != null; } function warn(msg) { if (hooks.suppressDeprecationWarnings === false && typeof console !== "undefined" && console.warn) { console.warn("Deprecation warning: " + msg); } } function deprecate(msg, fn2) { var firstTime = true; return extend(function() { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(null, msg); } if (firstTime) { var args = [], arg, i2, key, argLen = arguments.length; for (i2 = 0; i2 < argLen; i2++) { arg = ""; if (typeof arguments[i2] === "object") { arg += "\n[" + i2 + "] "; for (key in arguments[0]) { if (hasOwnProp(arguments[0], key)) { arg += key + ": " + arguments[0][key] + ", "; } } arg = arg.slice(0, -2); } else { arg = arguments[i2]; } args.push(arg); } warn( msg + "\nArguments: " + Array.prototype.slice.call(args).join("") + "\n" + new Error().stack ); firstTime = false; } return fn2.apply(this, arguments); }, fn2); } var deprecations = {}; function deprecateSimple(name, msg) { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(name, msg); } if (!deprecations[name]) { warn(msg); deprecations[name] = true; } } hooks.suppressDeprecationWarnings = false; hooks.deprecationHandler = null; function isFunction2(input) { return typeof Function !== "undefined" && input instanceof Function || Object.prototype.toString.call(input) === "[object Function]"; } function set2(config) { var prop, i2; for (i2 in config) { if (hasOwnProp(config, i2)) { prop = config[i2]; if (isFunction2(prop)) { this[i2] = prop; } else { this["_" + i2] = prop; } } } this._config = config; this._dayOfMonthOrdinalParseLenient = new RegExp( (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + "|" + /\d{1,2}/.source ); } function mergeConfigs(parentConfig, childConfig) { var res = extend({}, parentConfig), prop; for (prop in childConfig) { if (hasOwnProp(childConfig, prop)) { if (isObject2(parentConfig[prop]) && isObject2(childConfig[prop])) { res[prop] = {}; extend(res[prop], parentConfig[prop]); extend(res[prop], childConfig[prop]); } else if (childConfig[prop] != null) { res[prop] = childConfig[prop]; } else { delete res[prop]; } } } for (prop in parentConfig) { if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject2(parentConfig[prop])) { res[prop] = extend({}, res[prop]); } } return res; } function Locale(config) { if (config != null) { this.set(config); } } var keys; if (Object.keys) { keys = Object.keys; } else { keys = function(obj) { var i2, res = []; for (i2 in obj) { if (hasOwnProp(obj, i2)) { res.push(i2); } } return res; }; } var defaultCalendar = { sameDay: "[Today at] LT", nextDay: "[Tomorrow at] LT", nextWeek: "dddd [at] LT", lastDay: "[Yesterday at] LT", lastWeek: "[Last] dddd [at] LT", sameElse: "L" }; function calendar(key, mom, now3) { var output = this._calendar[key] || this._calendar["sameElse"]; return isFunction2(output) ? output.call(mom, now3) : output; } function zeroFill(number, targetLength, forceSign) { var absNumber = "" + Math.abs(number), zerosToFill = targetLength - absNumber.length, sign3 = number >= 0; return (sign3 ? forceSign ? "+" : "" : "-") + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; } var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, formatFunctions = {}, formatTokenFunctions = {}; function addFormatToken(token2, padded, ordinal2, callback2) { var func = callback2; if (typeof callback2 === "string") { func = function() { return this[callback2](); }; } if (token2) { formatTokenFunctions[token2] = func; } if (padded) { formatTokenFunctions[padded[0]] = function() { return zeroFill(func.apply(this, arguments), padded[1], padded[2]); }; } if (ordinal2) { formatTokenFunctions[ordinal2] = function() { return this.localeData().ordinal( func.apply(this, arguments), token2 ); }; } } function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { return input.replace(/^\[|\]$/g, ""); } return input.replace(/\\/g, ""); } function makeFormatFunction(format2) { var array = format2.match(formattingTokens), i2, length; for (i2 = 0, length = array.length; i2 < length; i2++) { if (formatTokenFunctions[array[i2]]) { array[i2] = formatTokenFunctions[array[i2]]; } else { array[i2] = removeFormattingTokens(array[i2]); } } return function(mom) { var output = "", i3; for (i3 = 0; i3 < length; i3++) { output += isFunction2(array[i3]) ? array[i3].call(mom, format2) : array[i3]; } return output; }; } function formatMoment(m2, format2) { if (!m2.isValid()) { return m2.localeData().invalidDate(); } format2 = expandFormat(format2, m2.localeData()); formatFunctions[format2] = formatFunctions[format2] || makeFormatFunction(format2); return formatFunctions[format2](m2); } function expandFormat(format2, locale3) { var i2 = 5; function replaceLongDateFormatTokens(input) { return locale3.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; while (i2 >= 0 && localFormattingTokens.test(format2)) { format2 = format2.replace( localFormattingTokens, replaceLongDateFormatTokens ); localFormattingTokens.lastIndex = 0; i2 -= 1; } return format2; } var defaultLongDateFormat = { LTS: "h:mm:ss A", LT: "h:mm A", L: "MM/DD/YYYY", LL: "MMMM D, YYYY", LLL: "MMMM D, YYYY h:mm A", LLLL: "dddd, MMMM D, YYYY h:mm A" }; function longDateFormat(key) { var format2 = this._longDateFormat[key], formatUpper = this._longDateFormat[key.toUpperCase()]; if (format2 || !formatUpper) { return format2; } this._longDateFormat[key] = formatUpper.match(formattingTokens).map(function(tok) { if (tok === "MMMM" || tok === "MM" || tok === "DD" || tok === "dddd") { return tok.slice(1); } return tok; }).join(""); return this._longDateFormat[key]; } var defaultInvalidDate = "Invalid date"; function invalidDate() { return this._invalidDate; } var defaultOrdinal = "%d", defaultDayOfMonthOrdinalParse = /\d{1,2}/; function ordinal(number) { return this._ordinal.replace("%d", number); } var defaultRelativeTime = { future: "in %s", past: "%s ago", s: "a few seconds", ss: "%d seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", w: "a week", ww: "%d weeks", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }; function relativeTime(number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return isFunction2(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); } function pastFuture(diff2, output) { var format2 = this._relativeTime[diff2 > 0 ? "future" : "past"]; return isFunction2(format2) ? format2(output) : format2.replace(/%s/i, output); } var aliases = { D: "date", dates: "date", date: "date", d: "day", days: "day", day: "day", e: "weekday", weekdays: "weekday", weekday: "weekday", E: "isoWeekday", isoweekdays: "isoWeekday", isoweekday: "isoWeekday", DDD: "dayOfYear", dayofyears: "dayOfYear", dayofyear: "dayOfYear", h: "hour", hours: "hour", hour: "hour", ms: "millisecond", milliseconds: "millisecond", millisecond: "millisecond", m: "minute", minutes: "minute", minute: "minute", M: "month", months: "month", month: "month", Q: "quarter", quarters: "quarter", quarter: "quarter", s: "second", seconds: "second", second: "second", gg: "weekYear", weekyears: "weekYear", weekyear: "weekYear", GG: "isoWeekYear", isoweekyears: "isoWeekYear", isoweekyear: "isoWeekYear", w: "week", weeks: "week", week: "week", W: "isoWeek", isoweeks: "isoWeek", isoweek: "isoWeek", y: "year", years: "year", year: "year" }; function normalizeUnits(units) { return typeof units === "string" ? aliases[units] || aliases[units.toLowerCase()] : void 0; } function normalizeObjectUnits(inputObject) { var normalizedInput = {}, normalizedProp, prop; for (prop in inputObject) { if (hasOwnProp(inputObject, prop)) { normalizedProp = normalizeUnits(prop); if (normalizedProp) { normalizedInput[normalizedProp] = inputObject[prop]; } } } return normalizedInput; } var priorities = { date: 9, day: 11, weekday: 11, isoWeekday: 11, dayOfYear: 4, hour: 13, millisecond: 16, minute: 14, month: 8, quarter: 7, second: 15, weekYear: 1, isoWeekYear: 1, week: 5, isoWeek: 5, year: 1 }; function getPrioritizedUnits(unitsObj) { var units = [], u2; for (u2 in unitsObj) { if (hasOwnProp(unitsObj, u2)) { units.push({ unit: u2, priority: priorities[u2] }); } } units.sort(function(a2, b2) { return a2.priority - b2.priority; }); return units; } var match1 = /\d/, match2 = /\d\d/, match3 = /\d{3}/, match4 = /\d{4}/, match6 = /[+-]?\d{6}/, match1to2 = /\d\d?/, match3to4 = /\d\d\d\d?/, match5to6 = /\d\d\d\d\d\d?/, match1to3 = /\d{1,3}/, match1to4 = /\d{1,4}/, match1to6 = /[+-]?\d{1,6}/, matchUnsigned = /\d+/, matchSigned = /[+-]?\d+/, matchOffset = /Z|[+-]\d\d:?\d\d/gi, matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, match1to2NoLeadingZero = /^[1-9]\d?/, match1to2HasZero = /^([1-9]\d|\d)/, regexes; regexes = {}; function addRegexToken(token2, regex, strictRegex) { regexes[token2] = isFunction2(regex) ? regex : function(isStrict, localeData2) { return isStrict && strictRegex ? strictRegex : regex; }; } function getParseRegexForToken(token2, config) { if (!hasOwnProp(regexes, token2)) { return new RegExp(unescapeFormat(token2)); } return regexes[token2](config._strict, config._locale); } function unescapeFormat(s2) { return regexEscape( s2.replace("\\", "").replace( /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(matched, p1, p2, p3, p4) { return p1 || p2 || p3 || p4; } ) ); } function regexEscape(s2) { return s2.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); } function absFloor(number) { if (number < 0) { return Math.ceil(number) || 0; } else { return Math.floor(number); } } function toInt(argumentForCoercion) { var coercedNumber = +argumentForCoercion, value = 0; if (coercedNumber !== 0 && isFinite(coercedNumber)) { value = absFloor(coercedNumber); } return value; } var tokens = {}; function addParseToken(token2, callback2) { var i2, func = callback2, tokenLen; if (typeof token2 === "string") { token2 = [token2]; } if (isNumber2(callback2)) { func = function(input, array) { array[callback2] = toInt(input); }; } tokenLen = token2.length; for (i2 = 0; i2 < tokenLen; i2++) { tokens[token2[i2]] = func; } } function addWeekParseToken(token2, callback2) { addParseToken(token2, function(input, array, config, token3) { config._w = config._w || {}; callback2(input, config._w, config, token3); }); } function addTimeToArrayFromToken(token2, input, config) { if (input != null && hasOwnProp(tokens, token2)) { tokens[token2](input, config._a, config, token2); } } function isLeapYear(year) { return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; } var YEAR = 0, MONTH = 1, DATE = 2, HOUR = 3, MINUTE = 4, SECOND = 5, MILLISECOND = 6, WEEK = 7, WEEKDAY = 8; addFormatToken("Y", 0, 0, function() { var y2 = this.year(); return y2 <= 9999 ? zeroFill(y2, 4) : "+" + y2; }); addFormatToken(0, ["YY", 2], 0, function() { return this.year() % 100; }); addFormatToken(0, ["YYYY", 4], 0, "year"); addFormatToken(0, ["YYYYY", 5], 0, "year"); addFormatToken(0, ["YYYYYY", 6, true], 0, "year"); addRegexToken("Y", matchSigned); addRegexToken("YY", match1to2, match2); addRegexToken("YYYY", match1to4, match4); addRegexToken("YYYYY", match1to6, match6); addRegexToken("YYYYYY", match1to6, match6); addParseToken(["YYYYY", "YYYYYY"], YEAR); addParseToken("YYYY", function(input, array) { array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); }); addParseToken("YY", function(input, array) { array[YEAR] = hooks.parseTwoDigitYear(input); }); addParseToken("Y", function(input, array) { array[YEAR] = parseInt(input, 10); }); function daysInYear(year) { return isLeapYear(year) ? 366 : 365; } hooks.parseTwoDigitYear = function(input) { return toInt(input) + (toInt(input) > 68 ? 1900 : 2e3); }; var getSetYear = makeGetSet("FullYear", true); function getIsLeapYear() { return isLeapYear(this.year()); } function makeGetSet(unit, keepTime) { return function(value) { if (value != null) { set$1(this, unit, value); hooks.updateOffset(this, keepTime); return this; } else { return get(this, unit); } }; } function get(mom, unit) { if (!mom.isValid()) { return NaN; } var d2 = mom._d, isUTC = mom._isUTC; switch (unit) { case "Milliseconds": return isUTC ? d2.getUTCMilliseconds() : d2.getMilliseconds(); case "Seconds": return isUTC ? d2.getUTCSeconds() : d2.getSeconds(); case "Minutes": return isUTC ? d2.getUTCMinutes() : d2.getMinutes(); case "Hours": return isUTC ? d2.getUTCHours() : d2.getHours(); case "Date": return isUTC ? d2.getUTCDate() : d2.getDate(); case "Day": return isUTC ? d2.getUTCDay() : d2.getDay(); case "Month": return isUTC ? d2.getUTCMonth() : d2.getMonth(); case "FullYear": return isUTC ? d2.getUTCFullYear() : d2.getFullYear(); default: return NaN; } } function set$1(mom, unit, value) { var d2, isUTC, year, month, date; if (!mom.isValid() || isNaN(value)) { return; } d2 = mom._d; isUTC = mom._isUTC; switch (unit) { case "Milliseconds": return void (isUTC ? d2.setUTCMilliseconds(value) : d2.setMilliseconds(value)); case "Seconds": return void (isUTC ? d2.setUTCSeconds(value) : d2.setSeconds(value)); case "Minutes": return void (isUTC ? d2.setUTCMinutes(value) : d2.setMinutes(value)); case "Hours": return void (isUTC ? d2.setUTCHours(value) : d2.setHours(value)); case "Date": return void (isUTC ? d2.setUTCDate(value) : d2.setDate(value)); // case 'Day': // Not real // return void (isUTC ? d.setUTCDay(value) : d.setDay(value)); // case 'Month': // Not used because we need to pass two variables // return void (isUTC ? d.setUTCMonth(value) : d.setMonth(value)); case "FullYear": break; // See below ... default: return; } year = value; month = mom.month(); date = mom.date(); date = date === 29 && month === 1 && !isLeapYear(year) ? 28 : date; void (isUTC ? d2.setUTCFullYear(year, month, date) : d2.setFullYear(year, month, date)); } function stringGet(units) { units = normalizeUnits(units); if (isFunction2(this[units])) { return this[units](); } return this; } function stringSet(units, value) { if (typeof units === "object") { units = normalizeObjectUnits(units); var prioritized = getPrioritizedUnits(units), i2, prioritizedLen = prioritized.length; for (i2 = 0; i2 < prioritizedLen; i2++) { this[prioritized[i2].unit](units[prioritized[i2].unit]); } } else { units = normalizeUnits(units); if (isFunction2(this[units])) { return this[units](value); } } return this; } function mod(n2, x2) { return (n2 % x2 + x2) % x2; } var indexOf; if (Array.prototype.indexOf) { indexOf = Array.prototype.indexOf; } else { indexOf = function(o2) { var i2; for (i2 = 0; i2 < this.length; ++i2) { if (this[i2] === o2) { return i2; } } return -1; }; } function daysInMonth(year, month) { if (isNaN(year) || isNaN(month)) { return NaN; } var modMonth = mod(month, 12); year += (month - modMonth) / 12; return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2; } addFormatToken("M", ["MM", 2], "Mo", function() { return this.month() + 1; }); addFormatToken("MMM", 0, 0, function(format2) { return this.localeData().monthsShort(this, format2); }); addFormatToken("MMMM", 0, 0, function(format2) { return this.localeData().months(this, format2); }); addRegexToken("M", match1to2, match1to2NoLeadingZero); addRegexToken("MM", match1to2, match2); addRegexToken("MMM", function(isStrict, locale3) { return locale3.monthsShortRegex(isStrict); }); addRegexToken("MMMM", function(isStrict, locale3) { return locale3.monthsRegex(isStrict); }); addParseToken(["M", "MM"], function(input, array) { array[MONTH] = toInt(input) - 1; }); addParseToken(["MMM", "MMMM"], function(input, array, config, token2) { var month = config._locale.monthsParse(input, token2, config._strict); if (month != null) { array[MONTH] = month; } else { getParsingFlags(config).invalidMonth = input; } }); var defaultLocaleMonths = "January_February_March_April_May_June_July_August_September_October_November_December".split( "_" ), defaultLocaleMonthsShort = "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, defaultMonthsShortRegex = matchWord, defaultMonthsRegex = matchWord; function localeMonths(m2, format2) { if (!m2) { return isArray2(this._months) ? this._months : this._months["standalone"]; } return isArray2(this._months) ? this._months[m2.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format2) ? "format" : "standalone"][m2.month()]; } function localeMonthsShort(m2, format2) { if (!m2) { return isArray2(this._monthsShort) ? this._monthsShort : this._monthsShort["standalone"]; } return isArray2(this._monthsShort) ? this._monthsShort[m2.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format2) ? "format" : "standalone"][m2.month()]; } function handleStrictParse(monthName, format2, strict) { var i2, ii, mom, llc = monthName.toLocaleLowerCase(); if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; for (i2 = 0; i2 < 12; ++i2) { mom = createUTC([2e3, i2]); this._shortMonthsParse[i2] = this.monthsShort( mom, "" ).toLocaleLowerCase(); this._longMonthsParse[i2] = this.months(mom, "").toLocaleLowerCase(); } } if (strict) { if (format2 === "MMM") { ii = indexOf.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } } else { if (format2 === "MMM") { ii = indexOf.call(this._shortMonthsParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._longMonthsParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } } } function localeMonthsParse(monthName, format2, strict) { var i2, mom, regex; if (this._monthsParseExact) { return handleStrictParse.call(this, monthName, format2, strict); } if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; } for (i2 = 0; i2 < 12; i2++) { mom = createUTC([2e3, i2]); if (strict && !this._longMonthsParse[i2]) { this._longMonthsParse[i2] = new RegExp( "^" + this.months(mom, "").replace(".", "") + "$", "i" ); this._shortMonthsParse[i2] = new RegExp( "^" + this.monthsShort(mom, "").replace(".", "") + "$", "i" ); } if (!strict && !this._monthsParse[i2]) { regex = "^" + this.months(mom, "") + "|^" + this.monthsShort(mom, ""); this._monthsParse[i2] = new RegExp(regex.replace(".", ""), "i"); } if (strict && format2 === "MMMM" && this._longMonthsParse[i2].test(monthName)) { return i2; } else if (strict && format2 === "MMM" && this._shortMonthsParse[i2].test(monthName)) { return i2; } else if (!strict && this._monthsParse[i2].test(monthName)) { return i2; } } } function setMonth(mom, value) { if (!mom.isValid()) { return mom; } if (typeof value === "string") { if (/^\d+$/.test(value)) { value = toInt(value); } else { value = mom.localeData().monthsParse(value); if (!isNumber2(value)) { return mom; } } } var month = value, date = mom.date(); date = date < 29 ? date : Math.min(date, daysInMonth(mom.year(), month)); void (mom._isUTC ? mom._d.setUTCMonth(month, date) : mom._d.setMonth(month, date)); return mom; } function getSetMonth(value) { if (value != null) { setMonth(this, value); hooks.updateOffset(this, true); return this; } else { return get(this, "Month"); } } function getDaysInMonth() { return daysInMonth(this.year(), this.month()); } function monthsShortRegex(isStrict) { if (this._monthsParseExact) { if (!hasOwnProp(this, "_monthsRegex")) { computeMonthsParse.call(this); } if (isStrict) { return this._monthsShortStrictRegex; } else { return this._monthsShortRegex; } } else { if (!hasOwnProp(this, "_monthsShortRegex")) { this._monthsShortRegex = defaultMonthsShortRegex; } return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex; } } function monthsRegex(isStrict) { if (this._monthsParseExact) { if (!hasOwnProp(this, "_monthsRegex")) { computeMonthsParse.call(this); } if (isStrict) { return this._monthsStrictRegex; } else { return this._monthsRegex; } } else { if (!hasOwnProp(this, "_monthsRegex")) { this._monthsRegex = defaultMonthsRegex; } return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex; } } function computeMonthsParse() { function cmpLenRev(a2, b2) { return b2.length - a2.length; } var shortPieces = [], longPieces = [], mixedPieces = [], i2, mom, shortP, longP; for (i2 = 0; i2 < 12; i2++) { mom = createUTC([2e3, i2]); shortP = regexEscape(this.monthsShort(mom, "")); longP = regexEscape(this.months(mom, "")); shortPieces.push(shortP); longPieces.push(longP); mixedPieces.push(longP); mixedPieces.push(shortP); } shortPieces.sort(cmpLenRev); longPieces.sort(cmpLenRev); mixedPieces.sort(cmpLenRev); this._monthsRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i"); this._monthsShortRegex = this._monthsRegex; this._monthsStrictRegex = new RegExp( "^(" + longPieces.join("|") + ")", "i" ); this._monthsShortStrictRegex = new RegExp( "^(" + shortPieces.join("|") + ")", "i" ); } function createDate(y2, m2, d2, h6, M2, s2, ms) { var date; if (y2 < 100 && y2 >= 0) { date = new Date(y2 + 400, m2, d2, h6, M2, s2, ms); if (isFinite(date.getFullYear())) { date.setFullYear(y2); } } else { date = new Date(y2, m2, d2, h6, M2, s2, ms); } return date; } function createUTCDate(y2) { var date, args; if (y2 < 100 && y2 >= 0) { args = Array.prototype.slice.call(arguments); args[0] = y2 + 400; date = new Date(Date.UTC.apply(null, args)); if (isFinite(date.getUTCFullYear())) { date.setUTCFullYear(y2); } } else { date = new Date(Date.UTC.apply(null, arguments)); } return date; } function firstWeekOffset(year, dow, doy) { var fwd = 7 + dow - doy, fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; return -fwdlw + fwd - 1; } function dayOfYearFromWeeks(year, week, weekday, dow, doy) { var localWeekday = (7 + weekday - dow) % 7, weekOffset = firstWeekOffset(year, dow, doy), dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, resYear, resDayOfYear; if (dayOfYear <= 0) { resYear = year - 1; resDayOfYear = daysInYear(resYear) + dayOfYear; } else if (dayOfYear > daysInYear(year)) { resYear = year + 1; resDayOfYear = dayOfYear - daysInYear(year); } else { resYear = year; resDayOfYear = dayOfYear; } return { year: resYear, dayOfYear: resDayOfYear }; } function weekOfYear(mom, dow, doy) { var weekOffset = firstWeekOffset(mom.year(), dow, doy), week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, resWeek, resYear; if (week < 1) { resYear = mom.year() - 1; resWeek = week + weeksInYear(resYear, dow, doy); } else if (week > weeksInYear(mom.year(), dow, doy)) { resWeek = week - weeksInYear(mom.year(), dow, doy); resYear = mom.year() + 1; } else { resYear = mom.year(); resWeek = week; } return { week: resWeek, year: resYear }; } function weeksInYear(year, dow, doy) { var weekOffset = firstWeekOffset(year, dow, doy), weekOffsetNext = firstWeekOffset(year + 1, dow, doy); return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; } addFormatToken("w", ["ww", 2], "wo", "week"); addFormatToken("W", ["WW", 2], "Wo", "isoWeek"); addRegexToken("w", match1to2, match1to2NoLeadingZero); addRegexToken("ww", match1to2, match2); addRegexToken("W", match1to2, match1to2NoLeadingZero); addRegexToken("WW", match1to2, match2); addWeekParseToken( ["w", "ww", "W", "WW"], function(input, week, config, token2) { week[token2.substr(0, 1)] = toInt(input); } ); function localeWeek(mom) { return weekOfYear(mom, this._week.dow, this._week.doy).week; } var defaultLocaleWeek = { dow: 0, // Sunday is the first day of the week. doy: 6 // The week that contains Jan 6th is the first week of the year. }; function localeFirstDayOfWeek() { return this._week.dow; } function localeFirstDayOfYear() { return this._week.doy; } function getSetWeek(input) { var week = this.localeData().week(this); return input == null ? week : this.add((input - week) * 7, "d"); } function getSetISOWeek(input) { var week = weekOfYear(this, 1, 4).week; return input == null ? week : this.add((input - week) * 7, "d"); } addFormatToken("d", 0, "do", "day"); addFormatToken("dd", 0, 0, function(format2) { return this.localeData().weekdaysMin(this, format2); }); addFormatToken("ddd", 0, 0, function(format2) { return this.localeData().weekdaysShort(this, format2); }); addFormatToken("dddd", 0, 0, function(format2) { return this.localeData().weekdays(this, format2); }); addFormatToken("e", 0, 0, "weekday"); addFormatToken("E", 0, 0, "isoWeekday"); addRegexToken("d", match1to2); addRegexToken("e", match1to2); addRegexToken("E", match1to2); addRegexToken("dd", function(isStrict, locale3) { return locale3.weekdaysMinRegex(isStrict); }); addRegexToken("ddd", function(isStrict, locale3) { return locale3.weekdaysShortRegex(isStrict); }); addRegexToken("dddd", function(isStrict, locale3) { return locale3.weekdaysRegex(isStrict); }); addWeekParseToken(["dd", "ddd", "dddd"], function(input, week, config, token2) { var weekday = config._locale.weekdaysParse(input, token2, config._strict); if (weekday != null) { week.d = weekday; } else { getParsingFlags(config).invalidWeekday = input; } }); addWeekParseToken(["d", "e", "E"], function(input, week, config, token2) { week[token2] = toInt(input); }); function parseWeekday(input, locale3) { if (typeof input !== "string") { return input; } if (!isNaN(input)) { return parseInt(input, 10); } input = locale3.weekdaysParse(input); if (typeof input === "number") { return input; } return null; } function parseIsoWeekday(input, locale3) { if (typeof input === "string") { return locale3.weekdaysParse(input) % 7 || 7; } return isNaN(input) ? null : input; } function shiftWeekdays(ws, n2) { return ws.slice(n2, 7).concat(ws.slice(0, n2)); } var defaultLocaleWeekdays = "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), defaultLocaleWeekdaysShort = "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), defaultLocaleWeekdaysMin = "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), defaultWeekdaysRegex = matchWord, defaultWeekdaysShortRegex = matchWord, defaultWeekdaysMinRegex = matchWord; function localeWeekdays(m2, format2) { var weekdays = isArray2(this._weekdays) ? this._weekdays : this._weekdays[m2 && m2 !== true && this._weekdays.isFormat.test(format2) ? "format" : "standalone"]; return m2 === true ? shiftWeekdays(weekdays, this._week.dow) : m2 ? weekdays[m2.day()] : weekdays; } function localeWeekdaysShort(m2) { return m2 === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m2 ? this._weekdaysShort[m2.day()] : this._weekdaysShort; } function localeWeekdaysMin(m2) { return m2 === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m2 ? this._weekdaysMin[m2.day()] : this._weekdaysMin; } function handleStrictParse$1(weekdayName, format2, strict) { var i2, ii, mom, llc = weekdayName.toLocaleLowerCase(); if (!this._weekdaysParse) { this._weekdaysParse = []; this._shortWeekdaysParse = []; this._minWeekdaysParse = []; for (i2 = 0; i2 < 7; ++i2) { mom = createUTC([2e3, 1]).day(i2); this._minWeekdaysParse[i2] = this.weekdaysMin( mom, "" ).toLocaleLowerCase(); this._shortWeekdaysParse[i2] = this.weekdaysShort( mom, "" ).toLocaleLowerCase(); this._weekdaysParse[i2] = this.weekdays(mom, "").toLocaleLowerCase(); } } if (strict) { if (format2 === "dddd") { ii = indexOf.call(this._weekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format2 === "ddd") { ii = indexOf.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } } else { if (format2 === "dddd") { ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format2 === "ddd") { ii = indexOf.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._minWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } } } function localeWeekdaysParse(weekdayName, format2, strict) { var i2, mom, regex; if (this._weekdaysParseExact) { return handleStrictParse$1.call(this, weekdayName, format2, strict); } if (!this._weekdaysParse) { this._weekdaysParse = []; this._minWeekdaysParse = []; this._shortWeekdaysParse = []; this._fullWeekdaysParse = []; } for (i2 = 0; i2 < 7; i2++) { mom = createUTC([2e3, 1]).day(i2); if (strict && !this._fullWeekdaysParse[i2]) { this._fullWeekdaysParse[i2] = new RegExp( "^" + this.weekdays(mom, "").replace(".", "\\.?") + "$", "i" ); this._shortWeekdaysParse[i2] = new RegExp( "^" + this.weekdaysShort(mom, "").replace(".", "\\.?") + "$", "i" ); this._minWeekdaysParse[i2] = new RegExp( "^" + this.weekdaysMin(mom, "").replace(".", "\\.?") + "$", "i" ); } if (!this._weekdaysParse[i2]) { regex = "^" + this.weekdays(mom, "") + "|^" + this.weekdaysShort(mom, "") + "|^" + this.weekdaysMin(mom, ""); this._weekdaysParse[i2] = new RegExp(regex.replace(".", ""), "i"); } if (strict && format2 === "dddd" && this._fullWeekdaysParse[i2].test(weekdayName)) { return i2; } else if (strict && format2 === "ddd" && this._shortWeekdaysParse[i2].test(weekdayName)) { return i2; } else if (strict && format2 === "dd" && this._minWeekdaysParse[i2].test(weekdayName)) { return i2; } else if (!strict && this._weekdaysParse[i2].test(weekdayName)) { return i2; } } } function getSetDayOfWeek(input) { if (!this.isValid()) { return input != null ? this : NaN; } var day = get(this, "Day"); if (input != null) { input = parseWeekday(input, this.localeData()); return this.add(input - day, "d"); } else { return day; } } function getSetLocaleDayOfWeek(input) { if (!this.isValid()) { return input != null ? this : NaN; } var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; return input == null ? weekday : this.add(input - weekday, "d"); } function getSetISODayOfWeek(input) { if (!this.isValid()) { return input != null ? this : NaN; } if (input != null) { var weekday = parseIsoWeekday(input, this.localeData()); return this.day(this.day() % 7 ? weekday : weekday - 7); } else { return this.day() || 7; } } function weekdaysRegex(isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, "_weekdaysRegex")) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysStrictRegex; } else { return this._weekdaysRegex; } } else { if (!hasOwnProp(this, "_weekdaysRegex")) { this._weekdaysRegex = defaultWeekdaysRegex; } return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex; } } function weekdaysShortRegex(isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, "_weekdaysRegex")) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysShortStrictRegex; } else { return this._weekdaysShortRegex; } } else { if (!hasOwnProp(this, "_weekdaysShortRegex")) { this._weekdaysShortRegex = defaultWeekdaysShortRegex; } return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex; } } function weekdaysMinRegex(isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, "_weekdaysRegex")) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysMinStrictRegex; } else { return this._weekdaysMinRegex; } } else { if (!hasOwnProp(this, "_weekdaysMinRegex")) { this._weekdaysMinRegex = defaultWeekdaysMinRegex; } return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex; } } function computeWeekdaysParse() { function cmpLenRev(a2, b2) { return b2.length - a2.length; } var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], i2, mom, minp, shortp, longp; for (i2 = 0; i2 < 7; i2++) { mom = createUTC([2e3, 1]).day(i2); minp = regexEscape(this.weekdaysMin(mom, "")); shortp = regexEscape(this.weekdaysShort(mom, "")); longp = regexEscape(this.weekdays(mom, "")); minPieces.push(minp); shortPieces.push(shortp); longPieces.push(longp); mixedPieces.push(minp); mixedPieces.push(shortp); mixedPieces.push(longp); } minPieces.sort(cmpLenRev); shortPieces.sort(cmpLenRev); longPieces.sort(cmpLenRev); mixedPieces.sort(cmpLenRev); this._weekdaysRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i"); this._weekdaysShortRegex = this._weekdaysRegex; this._weekdaysMinRegex = this._weekdaysRegex; this._weekdaysStrictRegex = new RegExp( "^(" + longPieces.join("|") + ")", "i" ); this._weekdaysShortStrictRegex = new RegExp( "^(" + shortPieces.join("|") + ")", "i" ); this._weekdaysMinStrictRegex = new RegExp( "^(" + minPieces.join("|") + ")", "i" ); } function hFormat() { return this.hours() % 12 || 12; } function kFormat() { return this.hours() || 24; } addFormatToken("H", ["HH", 2], 0, "hour"); addFormatToken("h", ["hh", 2], 0, hFormat); addFormatToken("k", ["kk", 2], 0, kFormat); addFormatToken("hmm", 0, 0, function() { return "" + hFormat.apply(this) + zeroFill(this.minutes(), 2); }); addFormatToken("hmmss", 0, 0, function() { return "" + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); }); addFormatToken("Hmm", 0, 0, function() { return "" + this.hours() + zeroFill(this.minutes(), 2); }); addFormatToken("Hmmss", 0, 0, function() { return "" + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); }); function meridiem(token2, lowercase) { addFormatToken(token2, 0, 0, function() { return this.localeData().meridiem( this.hours(), this.minutes(), lowercase ); }); } meridiem("a", true); meridiem("A", false); function matchMeridiem(isStrict, locale3) { return locale3._meridiemParse; } addRegexToken("a", matchMeridiem); addRegexToken("A", matchMeridiem); addRegexToken("H", match1to2, match1to2HasZero); addRegexToken("h", match1to2, match1to2NoLeadingZero); addRegexToken("k", match1to2, match1to2NoLeadingZero); addRegexToken("HH", match1to2, match2); addRegexToken("hh", match1to2, match2); addRegexToken("kk", match1to2, match2); addRegexToken("hmm", match3to4); addRegexToken("hmmss", match5to6); addRegexToken("Hmm", match3to4); addRegexToken("Hmmss", match5to6); addParseToken(["H", "HH"], HOUR); addParseToken(["k", "kk"], function(input, array, config) { var kInput = toInt(input); array[HOUR] = kInput === 24 ? 0 : kInput; }); addParseToken(["a", "A"], function(input, array, config) { config._isPm = config._locale.isPM(input); config._meridiem = input; }); addParseToken(["h", "hh"], function(input, array, config) { array[HOUR] = toInt(input); getParsingFlags(config).bigHour = true; }); addParseToken("hmm", function(input, array, config) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); getParsingFlags(config).bigHour = true; }); addParseToken("hmmss", function(input, array, config) { var pos1 = input.length - 4, pos2 = input.length - 2; array[HOUR] = toInt(input.substr(0, pos1)); array[MINUTE] = toInt(input.substr(pos1, 2)); array[SECOND] = toInt(input.substr(pos2)); getParsingFlags(config).bigHour = true; }); addParseToken("Hmm", function(input, array, config) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); }); addParseToken("Hmmss", function(input, array, config) { var pos1 = input.length - 4, pos2 = input.length - 2; array[HOUR] = toInt(input.substr(0, pos1)); array[MINUTE] = toInt(input.substr(pos1, 2)); array[SECOND] = toInt(input.substr(pos2)); }); function localeIsPM(input) { return (input + "").toLowerCase().charAt(0) === "p"; } var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i, getSetHour = makeGetSet("Hours", true); function localeMeridiem(hours2, minutes2, isLower) { if (hours2 > 11) { return isLower ? "pm" : "PM"; } else { return isLower ? "am" : "AM"; } } var baseConfig = { calendar: defaultCalendar, longDateFormat: defaultLongDateFormat, invalidDate: defaultInvalidDate, ordinal: defaultOrdinal, dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, relativeTime: defaultRelativeTime, months: defaultLocaleMonths, monthsShort: defaultLocaleMonthsShort, week: defaultLocaleWeek, weekdays: defaultLocaleWeekdays, weekdaysMin: defaultLocaleWeekdaysMin, weekdaysShort: defaultLocaleWeekdaysShort, meridiemParse: defaultLocaleMeridiemParse }; var locales = {}, localeFamilies = {}, globalLocale; function commonPrefix(arr1, arr2) { var i2, minl = Math.min(arr1.length, arr2.length); for (i2 = 0; i2 < minl; i2 += 1) { if (arr1[i2] !== arr2[i2]) { return i2; } } return minl; } function normalizeLocale(key) { return key ? key.toLowerCase().replace("_", "-") : key; } function chooseLocale(names2) { var i2 = 0, j2, next, locale3, split; while (i2 < names2.length) { split = normalizeLocale(names2[i2]).split("-"); j2 = split.length; next = normalizeLocale(names2[i2 + 1]); next = next ? next.split("-") : null; while (j2 > 0) { locale3 = loadLocale(split.slice(0, j2).join("-")); if (locale3) { return locale3; } if (next && next.length >= j2 && commonPrefix(split, next) >= j2 - 1) { break; } j2--; } i2++; } return globalLocale; } function isLocaleNameSane(name) { return !!(name && name.match("^[^/\\\\]*$")); } function loadLocale(name) { var oldLocale = null, aliasedRequire; if (locales[name] === void 0 && typeof module2 !== "undefined" && module2 && module2.exports && isLocaleNameSane(name)) { try { oldLocale = globalLocale._abbr; aliasedRequire = require; aliasedRequire("./locale/" + name); getSetGlobalLocale(oldLocale); } catch (e2) { locales[name] = null; } } return locales[name]; } function getSetGlobalLocale(key, values) { var data; if (key) { if (isUndefined(values)) { data = getLocale(key); } else { data = defineLocale(key, values); } if (data) { globalLocale = data; } else { if (typeof console !== "undefined" && console.warn) { console.warn( "Locale " + key + " not found. Did you forget to load it?" ); } } } return globalLocale._abbr; } function defineLocale(name, config) { if (config !== null) { var locale3, parentConfig = baseConfig; config.abbr = name; if (locales[name] != null) { deprecateSimple( "defineLocaleOverride", "use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info." ); parentConfig = locales[name]._config; } else if (config.parentLocale != null) { if (locales[config.parentLocale] != null) { parentConfig = locales[config.parentLocale]._config; } else { locale3 = loadLocale(config.parentLocale); if (locale3 != null) { parentConfig = locale3._config; } else { if (!localeFamilies[config.parentLocale]) { localeFamilies[config.parentLocale] = []; } localeFamilies[config.parentLocale].push({ name, config }); return null; } } } locales[name] = new Locale(mergeConfigs(parentConfig, config)); if (localeFamilies[name]) { localeFamilies[name].forEach(function(x2) { defineLocale(x2.name, x2.config); }); } getSetGlobalLocale(name); return locales[name]; } else { delete locales[name]; return null; } } function updateLocale(name, config) { if (config != null) { var locale3, tmpLocale, parentConfig = baseConfig; if (locales[name] != null && locales[name].parentLocale != null) { locales[name].set(mergeConfigs(locales[name]._config, config)); } else { tmpLocale = loadLocale(name); if (tmpLocale != null) { parentConfig = tmpLocale._config; } config = mergeConfigs(parentConfig, config); if (tmpLocale == null) { config.abbr = name; } locale3 = new Locale(config); locale3.parentLocale = locales[name]; locales[name] = locale3; } getSetGlobalLocale(name); } else { if (locales[name] != null) { if (locales[name].parentLocale != null) { locales[name] = locales[name].parentLocale; if (name === getSetGlobalLocale()) { getSetGlobalLocale(name); } } else if (locales[name] != null) { delete locales[name]; } } } return locales[name]; } function getLocale(key) { var locale3; if (key && key._locale && key._locale._abbr) { key = key._locale._abbr; } if (!key) { return globalLocale; } if (!isArray2(key)) { locale3 = loadLocale(key); if (locale3) { return locale3; } key = [key]; } return chooseLocale(key); } function listLocales() { return keys(locales); } function checkOverflow(m2) { var overflow, a2 = m2._a; if (a2 && getParsingFlags(m2).overflow === -2) { overflow = a2[MONTH] < 0 || a2[MONTH] > 11 ? MONTH : a2[DATE] < 1 || a2[DATE] > daysInMonth(a2[YEAR], a2[MONTH]) ? DATE : a2[HOUR] < 0 || a2[HOUR] > 24 || a2[HOUR] === 24 && (a2[MINUTE] !== 0 || a2[SECOND] !== 0 || a2[MILLISECOND] !== 0) ? HOUR : a2[MINUTE] < 0 || a2[MINUTE] > 59 ? MINUTE : a2[SECOND] < 0 || a2[SECOND] > 59 ? SECOND : a2[MILLISECOND] < 0 || a2[MILLISECOND] > 999 ? MILLISECOND : -1; if (getParsingFlags(m2)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { overflow = DATE; } if (getParsingFlags(m2)._overflowWeeks && overflow === -1) { overflow = WEEK; } if (getParsingFlags(m2)._overflowWeekday && overflow === -1) { overflow = WEEKDAY; } getParsingFlags(m2).overflow = overflow; } return m2; } var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, isoDates = [ ["YYYYYY-MM-DD", /[+-]\d{6}-\d\d-\d\d/], ["YYYY-MM-DD", /\d{4}-\d\d-\d\d/], ["GGGG-[W]WW-E", /\d{4}-W\d\d-\d/], ["GGGG-[W]WW", /\d{4}-W\d\d/, false], ["YYYY-DDD", /\d{4}-\d{3}/], ["YYYY-MM", /\d{4}-\d\d/, false], ["YYYYYYMMDD", /[+-]\d{10}/], ["YYYYMMDD", /\d{8}/], ["GGGG[W]WWE", /\d{4}W\d{3}/], ["GGGG[W]WW", /\d{4}W\d{2}/, false], ["YYYYDDD", /\d{7}/], ["YYYYMM", /\d{6}/, false], ["YYYY", /\d{4}/, false] ], isoTimes = [ ["HH:mm:ss.SSSS", /\d\d:\d\d:\d\d\.\d+/], ["HH:mm:ss,SSSS", /\d\d:\d\d:\d\d,\d+/], ["HH:mm:ss", /\d\d:\d\d:\d\d/], ["HH:mm", /\d\d:\d\d/], ["HHmmss.SSSS", /\d\d\d\d\d\d\.\d+/], ["HHmmss,SSSS", /\d\d\d\d\d\d,\d+/], ["HHmmss", /\d\d\d\d\d\d/], ["HHmm", /\d\d\d\d/], ["HH", /\d\d/] ], aspNetJsonRegex = /^\/?Date\((-?\d+)/i, rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, obsOffsets = { UT: 0, GMT: 0, EDT: -4 * 60, EST: -5 * 60, CDT: -5 * 60, CST: -6 * 60, MDT: -6 * 60, MST: -7 * 60, PDT: -7 * 60, PST: -8 * 60 }; function configFromISO(config) { var i2, l2, string = config._i, match5 = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), allowTime, dateFormat, timeFormat, tzFormat, isoDatesLen = isoDates.length, isoTimesLen = isoTimes.length; if (match5) { getParsingFlags(config).iso = true; for (i2 = 0, l2 = isoDatesLen; i2 < l2; i2++) { if (isoDates[i2][1].exec(match5[1])) { dateFormat = isoDates[i2][0]; allowTime = isoDates[i2][2] !== false; break; } } if (dateFormat == null) { config._isValid = false; return; } if (match5[3]) { for (i2 = 0, l2 = isoTimesLen; i2 < l2; i2++) { if (isoTimes[i2][1].exec(match5[3])) { timeFormat = (match5[2] || " ") + isoTimes[i2][0]; break; } } if (timeFormat == null) { config._isValid = false; return; } } if (!allowTime && timeFormat != null) { config._isValid = false; return; } if (match5[4]) { if (tzRegex.exec(match5[4])) { tzFormat = "Z"; } else { config._isValid = false; return; } } config._f = dateFormat + (timeFormat || "") + (tzFormat || ""); configFromStringAndFormat(config); } else { config._isValid = false; } } function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { var result = [ untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10) ]; if (secondStr) { result.push(parseInt(secondStr, 10)); } return result; } function untruncateYear(yearStr) { var year = parseInt(yearStr, 10); if (year <= 49) { return 2e3 + year; } else if (year <= 999) { return 1900 + year; } return year; } function preprocessRFC2822(s2) { return s2.replace(/\([^()]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").replace(/^\s\s*/, "").replace(/\s\s*$/, ""); } function checkWeekday(weekdayStr, parsedInput, config) { if (weekdayStr) { var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), weekdayActual = new Date( parsedInput[0], parsedInput[1], parsedInput[2] ).getDay(); if (weekdayProvided !== weekdayActual) { getParsingFlags(config).weekdayMismatch = true; config._isValid = false; return false; } } return true; } function calculateOffset(obsOffset, militaryOffset, numOffset) { if (obsOffset) { return obsOffsets[obsOffset]; } else if (militaryOffset) { return 0; } else { var hm = parseInt(numOffset, 10), m2 = hm % 100, h6 = (hm - m2) / 100; return h6 * 60 + m2; } } function configFromRFC2822(config) { var match5 = rfc2822.exec(preprocessRFC2822(config._i)), parsedArray; if (match5) { parsedArray = extractFromRFC2822Strings( match5[4], match5[3], match5[2], match5[5], match5[6], match5[7] ); if (!checkWeekday(match5[1], parsedArray, config)) { return; } config._a = parsedArray; config._tzm = calculateOffset(match5[8], match5[9], match5[10]); config._d = createUTCDate.apply(null, config._a); config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); getParsingFlags(config).rfc2822 = true; } else { config._isValid = false; } } function configFromString(config) { var matched = aspNetJsonRegex.exec(config._i); if (matched !== null) { config._d = /* @__PURE__ */ new Date(+matched[1]); return; } configFromISO(config); if (config._isValid === false) { delete config._isValid; } else { return; } configFromRFC2822(config); if (config._isValid === false) { delete config._isValid; } else { return; } if (config._strict) { config._isValid = false; } else { hooks.createFromInputFallback(config); } } hooks.createFromInputFallback = deprecate( "value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.", function(config) { config._d = /* @__PURE__ */ new Date(config._i + (config._useUTC ? " UTC" : "")); } ); function defaults3(a2, b2, c2) { if (a2 != null) { return a2; } if (b2 != null) { return b2; } return c2; } function currentDateArray(config) { var nowValue = new Date(hooks.now()); if (config._useUTC) { return [ nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate() ]; } return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; } function configFromArray(config) { var i2, date, input = [], currentDate, expectedWeekday, yearToUse; if (config._d) { return; } currentDate = currentDateArray(config); if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { dayOfYearFromWeekInfo(config); } if (config._dayOfYear != null) { yearToUse = defaults3(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { getParsingFlags(config)._overflowDayOfYear = true; } date = createUTCDate(yearToUse, 0, config._dayOfYear); config._a[MONTH] = date.getUTCMonth(); config._a[DATE] = date.getUTCDate(); } for (i2 = 0; i2 < 3 && config._a[i2] == null; ++i2) { config._a[i2] = input[i2] = currentDate[i2]; } for (; i2 < 7; i2++) { config._a[i2] = input[i2] = config._a[i2] == null ? i2 === 2 ? 1 : 0 : config._a[i2]; } if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) { config._nextDay = true; config._a[HOUR] = 0; } config._d = (config._useUTC ? createUTCDate : createDate).apply( null, input ); expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); if (config._tzm != null) { config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); } if (config._nextDay) { config._a[HOUR] = 24; } if (config._w && typeof config._w.d !== "undefined" && config._w.d !== expectedWeekday) { getParsingFlags(config).weekdayMismatch = true; } } function dayOfYearFromWeekInfo(config) { var w2, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek; w2 = config._w; if (w2.GG != null || w2.W != null || w2.E != null) { dow = 1; doy = 4; weekYear = defaults3( w2.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year ); week = defaults3(w2.W, 1); weekday = defaults3(w2.E, 1); if (weekday < 1 || weekday > 7) { weekdayOverflow = true; } } else { dow = config._locale._week.dow; doy = config._locale._week.doy; curWeek = weekOfYear(createLocal(), dow, doy); weekYear = defaults3(w2.gg, config._a[YEAR], curWeek.year); week = defaults3(w2.w, curWeek.week); if (w2.d != null) { weekday = w2.d; if (weekday < 0 || weekday > 6) { weekdayOverflow = true; } } else if (w2.e != null) { weekday = w2.e + dow; if (w2.e < 0 || w2.e > 6) { weekdayOverflow = true; } } else { weekday = dow; } } if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { getParsingFlags(config)._overflowWeeks = true; } else if (weekdayOverflow != null) { getParsingFlags(config)._overflowWeekday = true; } else { temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); config._a[YEAR] = temp.year; config._dayOfYear = temp.dayOfYear; } } hooks.ISO_8601 = function() { }; hooks.RFC_2822 = function() { }; function configFromStringAndFormat(config) { if (config._f === hooks.ISO_8601) { configFromISO(config); return; } if (config._f === hooks.RFC_2822) { configFromRFC2822(config); return; } config._a = []; getParsingFlags(config).empty = true; var string = "" + config._i, i2, parsedInput, tokens2, token2, skipped, stringLength = string.length, totalParsedInputLength = 0, era, tokenLen; tokens2 = expandFormat(config._f, config._locale).match(formattingTokens) || []; tokenLen = tokens2.length; for (i2 = 0; i2 < tokenLen; i2++) { token2 = tokens2[i2]; parsedInput = (string.match(getParseRegexForToken(token2, config)) || [])[0]; if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { getParsingFlags(config).unusedInput.push(skipped); } string = string.slice( string.indexOf(parsedInput) + parsedInput.length ); totalParsedInputLength += parsedInput.length; } if (formatTokenFunctions[token2]) { if (parsedInput) { getParsingFlags(config).empty = false; } else { getParsingFlags(config).unusedTokens.push(token2); } addTimeToArrayFromToken(token2, parsedInput, config); } else if (config._strict && !parsedInput) { getParsingFlags(config).unusedTokens.push(token2); } } getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; if (string.length > 0) { getParsingFlags(config).unusedInput.push(string); } if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) { getParsingFlags(config).bigHour = void 0; } getParsingFlags(config).parsedDateParts = config._a.slice(0); getParsingFlags(config).meridiem = config._meridiem; config._a[HOUR] = meridiemFixWrap( config._locale, config._a[HOUR], config._meridiem ); era = getParsingFlags(config).era; if (era !== null) { config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]); } configFromArray(config); checkOverflow(config); } function meridiemFixWrap(locale3, hour, meridiem2) { var isPm; if (meridiem2 == null) { return hour; } if (locale3.meridiemHour != null) { return locale3.meridiemHour(hour, meridiem2); } else if (locale3.isPM != null) { isPm = locale3.isPM(meridiem2); if (isPm && hour < 12) { hour += 12; } if (!isPm && hour === 12) { hour = 0; } return hour; } else { return hour; } } function configFromStringAndArray(config) { var tempConfig, bestMoment, scoreToBeat, i2, currentScore, validFormatFound, bestFormatIsValid = false, configfLen = config._f.length; if (configfLen === 0) { getParsingFlags(config).invalidFormat = true; config._d = /* @__PURE__ */ new Date(NaN); return; } for (i2 = 0; i2 < configfLen; i2++) { currentScore = 0; validFormatFound = false; tempConfig = copyConfig({}, config); if (config._useUTC != null) { tempConfig._useUTC = config._useUTC; } tempConfig._f = config._f[i2]; configFromStringAndFormat(tempConfig); if (isValid(tempConfig)) { validFormatFound = true; } currentScore += getParsingFlags(tempConfig).charsLeftOver; currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; getParsingFlags(tempConfig).score = currentScore; if (!bestFormatIsValid) { if (scoreToBeat == null || currentScore < scoreToBeat || validFormatFound) { scoreToBeat = currentScore; bestMoment = tempConfig; if (validFormatFound) { bestFormatIsValid = true; } } } else { if (currentScore < scoreToBeat) { scoreToBeat = currentScore; bestMoment = tempConfig; } } } extend(config, bestMoment || tempConfig); } function configFromObject(config) { if (config._d) { return; } var i2 = normalizeObjectUnits(config._i), dayOrDate = i2.day === void 0 ? i2.date : i2.day; config._a = map3( [i2.year, i2.month, dayOrDate, i2.hour, i2.minute, i2.second, i2.millisecond], function(obj) { return obj && parseInt(obj, 10); } ); configFromArray(config); } function createFromConfig(config) { var res = new Moment3(checkOverflow(prepareConfig(config))); if (res._nextDay) { res.add(1, "d"); res._nextDay = void 0; } return res; } function prepareConfig(config) { var input = config._i, format2 = config._f; config._locale = config._locale || getLocale(config._l); if (input === null || format2 === void 0 && input === "") { return createInvalid({ nullInput: true }); } if (typeof input === "string") { config._i = input = config._locale.preparse(input); } if (isMoment(input)) { return new Moment3(checkOverflow(input)); } else if (isDate(input)) { config._d = input; } else if (isArray2(format2)) { configFromStringAndArray(config); } else if (format2) { configFromStringAndFormat(config); } else { configFromInput(config); } if (!isValid(config)) { config._d = null; } return config; } function configFromInput(config) { var input = config._i; if (isUndefined(input)) { config._d = new Date(hooks.now()); } else if (isDate(input)) { config._d = new Date(input.valueOf()); } else if (typeof input === "string") { configFromString(config); } else if (isArray2(input)) { config._a = map3(input.slice(0), function(obj) { return parseInt(obj, 10); }); configFromArray(config); } else if (isObject2(input)) { configFromObject(config); } else if (isNumber2(input)) { config._d = new Date(input); } else { hooks.createFromInputFallback(config); } } function createLocalOrUTC(input, format2, locale3, strict, isUTC) { var c2 = {}; if (format2 === true || format2 === false) { strict = format2; format2 = void 0; } if (locale3 === true || locale3 === false) { strict = locale3; locale3 = void 0; } if (isObject2(input) && isObjectEmpty(input) || isArray2(input) && input.length === 0) { input = void 0; } c2._isAMomentObject = true; c2._useUTC = c2._isUTC = isUTC; c2._l = locale3; c2._i = input; c2._f = format2; c2._strict = strict; return createFromConfig(c2); } function createLocal(input, format2, locale3, strict) { return createLocalOrUTC(input, format2, locale3, strict, false); } var prototypeMin = deprecate( "moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/", function() { var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other < this ? this : other; } else { return createInvalid(); } } ), prototypeMax = deprecate( "moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/", function() { var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other > this ? this : other; } else { return createInvalid(); } } ); function pickBy(fn2, moments) { var res, i2; if (moments.length === 1 && isArray2(moments[0])) { moments = moments[0]; } if (!moments.length) { return createLocal(); } res = moments[0]; for (i2 = 1; i2 < moments.length; ++i2) { if (!moments[i2].isValid() || moments[i2][fn2](res)) { res = moments[i2]; } } return res; } function min() { var args = [].slice.call(arguments, 0); return pickBy("isBefore", args); } function max() { var args = [].slice.call(arguments, 0); return pickBy("isAfter", args); } var now2 = function() { return Date.now ? Date.now() : +/* @__PURE__ */ new Date(); }; var ordering = [ "year", "quarter", "month", "week", "day", "hour", "minute", "second", "millisecond" ]; function isDurationValid(m2) { var key, unitHasDecimal = false, i2, orderLen = ordering.length; for (key in m2) { if (hasOwnProp(m2, key) && !(indexOf.call(ordering, key) !== -1 && (m2[key] == null || !isNaN(m2[key])))) { return false; } } for (i2 = 0; i2 < orderLen; ++i2) { if (m2[ordering[i2]]) { if (unitHasDecimal) { return false; } if (parseFloat(m2[ordering[i2]]) !== toInt(m2[ordering[i2]])) { unitHasDecimal = true; } } } return true; } function isValid$1() { return this._isValid; } function createInvalid$1() { return createDuration(NaN); } function Duration(duration) { var normalizedInput = normalizeObjectUnits(duration), years2 = normalizedInput.year || 0, quarters = normalizedInput.quarter || 0, months2 = normalizedInput.month || 0, weeks2 = normalizedInput.week || normalizedInput.isoWeek || 0, days2 = normalizedInput.day || 0, hours2 = normalizedInput.hour || 0, minutes2 = normalizedInput.minute || 0, seconds2 = normalizedInput.second || 0, milliseconds2 = normalizedInput.millisecond || 0; this._isValid = isDurationValid(normalizedInput); this._milliseconds = +milliseconds2 + seconds2 * 1e3 + // 1000 minutes2 * 6e4 + // 1000 * 60 hours2 * 1e3 * 60 * 60; this._days = +days2 + weeks2 * 7; this._months = +months2 + quarters * 3 + years2 * 12; this._data = {}; this._locale = getLocale(); this._bubble(); } function isDuration(obj) { return obj instanceof Duration; } function absRound(number) { if (number < 0) { return Math.round(-1 * number) * -1; } else { return Math.round(number); } } function compareArrays(array1, array2, dontConvert) { var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), diffs = 0, i2; for (i2 = 0; i2 < len; i2++) { if (dontConvert && array1[i2] !== array2[i2] || !dontConvert && toInt(array1[i2]) !== toInt(array2[i2])) { diffs++; } } return diffs + lengthDiff; } function offset(token2, separator) { addFormatToken(token2, 0, 0, function() { var offset2 = this.utcOffset(), sign3 = "+"; if (offset2 < 0) { offset2 = -offset2; sign3 = "-"; } return sign3 + zeroFill(~~(offset2 / 60), 2) + separator + zeroFill(~~offset2 % 60, 2); }); } offset("Z", ":"); offset("ZZ", ""); addRegexToken("Z", matchShortOffset); addRegexToken("ZZ", matchShortOffset); addParseToken(["Z", "ZZ"], function(input, array, config) { config._useUTC = true; config._tzm = offsetFromString(matchShortOffset, input); }); var chunkOffset = /([\+\-]|\d\d)/gi; function offsetFromString(matcher, string) { var matches = (string || "").match(matcher), chunk, parts, minutes2; if (matches === null) { return null; } chunk = matches[matches.length - 1] || []; parts = (chunk + "").match(chunkOffset) || ["-", 0, 0]; minutes2 = +(parts[1] * 60) + toInt(parts[2]); return minutes2 === 0 ? 0 : parts[0] === "+" ? minutes2 : -minutes2; } function cloneWithOffset(input, model) { var res, diff2; if (model._isUTC) { res = model.clone(); diff2 = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); res._d.setTime(res._d.valueOf() + diff2); hooks.updateOffset(res, false); return res; } else { return createLocal(input).local(); } } function getDateOffset(m2) { return -Math.round(m2._d.getTimezoneOffset()); } hooks.updateOffset = function() { }; function getSetOffset(input, keepLocalTime, keepMinutes) { var offset2 = this._offset || 0, localAdjust; if (!this.isValid()) { return input != null ? this : NaN; } if (input != null) { if (typeof input === "string") { input = offsetFromString(matchShortOffset, input); if (input === null) { return this; } } else if (Math.abs(input) < 16 && !keepMinutes) { input = input * 60; } if (!this._isUTC && keepLocalTime) { localAdjust = getDateOffset(this); } this._offset = input; this._isUTC = true; if (localAdjust != null) { this.add(localAdjust, "m"); } if (offset2 !== input) { if (!keepLocalTime || this._changeInProgress) { addSubtract( this, createDuration(input - offset2, "m"), 1, false ); } else if (!this._changeInProgress) { this._changeInProgress = true; hooks.updateOffset(this, true); this._changeInProgress = null; } } return this; } else { return this._isUTC ? offset2 : getDateOffset(this); } } function getSetZone(input, keepLocalTime) { if (input != null) { if (typeof input !== "string") { input = -input; } this.utcOffset(input, keepLocalTime); return this; } else { return -this.utcOffset(); } } function setOffsetToUTC(keepLocalTime) { return this.utcOffset(0, keepLocalTime); } function setOffsetToLocal(keepLocalTime) { if (this._isUTC) { this.utcOffset(0, keepLocalTime); this._isUTC = false; if (keepLocalTime) { this.subtract(getDateOffset(this), "m"); } } return this; } function setOffsetToParsedOffset() { if (this._tzm != null) { this.utcOffset(this._tzm, false, true); } else if (typeof this._i === "string") { var tZone = offsetFromString(matchOffset, this._i); if (tZone != null) { this.utcOffset(tZone); } else { this.utcOffset(0, true); } } return this; } function hasAlignedHourOffset(input) { if (!this.isValid()) { return false; } input = input ? createLocal(input).utcOffset() : 0; return (this.utcOffset() - input) % 60 === 0; } function isDaylightSavingTime() { return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset(); } function isDaylightSavingTimeShifted() { if (!isUndefined(this._isDSTShifted)) { return this._isDSTShifted; } var c2 = {}, other; copyConfig(c2, this); c2 = prepareConfig(c2); if (c2._a) { other = c2._isUTC ? createUTC(c2._a) : createLocal(c2._a); this._isDSTShifted = this.isValid() && compareArrays(c2._a, other.toArray()) > 0; } else { this._isDSTShifted = false; } return this._isDSTShifted; } function isLocal() { return this.isValid() ? !this._isUTC : false; } function isUtcOffset() { return this.isValid() ? this._isUTC : false; } function isUtc() { return this.isValid() ? this._isUTC && this._offset === 0 : false; } var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/, isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; function createDuration(input, key) { var duration = input, match5 = null, sign3, ret, diffRes; if (isDuration(input)) { duration = { ms: input._milliseconds, d: input._days, M: input._months }; } else if (isNumber2(input) || !isNaN(+input)) { duration = {}; if (key) { duration[key] = +input; } else { duration.milliseconds = +input; } } else if (match5 = aspNetRegex.exec(input)) { sign3 = match5[1] === "-" ? -1 : 1; duration = { y: 0, d: toInt(match5[DATE]) * sign3, h: toInt(match5[HOUR]) * sign3, m: toInt(match5[MINUTE]) * sign3, s: toInt(match5[SECOND]) * sign3, ms: toInt(absRound(match5[MILLISECOND] * 1e3)) * sign3 // the millisecond decimal point is included in the match }; } else if (match5 = isoRegex.exec(input)) { sign3 = match5[1] === "-" ? -1 : 1; duration = { y: parseIso(match5[2], sign3), M: parseIso(match5[3], sign3), w: parseIso(match5[4], sign3), d: parseIso(match5[5], sign3), h: parseIso(match5[6], sign3), m: parseIso(match5[7], sign3), s: parseIso(match5[8], sign3) }; } else if (duration == null) { duration = {}; } else if (typeof duration === "object" && ("from" in duration || "to" in duration)) { diffRes = momentsDifference( createLocal(duration.from), createLocal(duration.to) ); duration = {}; duration.ms = diffRes.milliseconds; duration.M = diffRes.months; } ret = new Duration(duration); if (isDuration(input) && hasOwnProp(input, "_locale")) { ret._locale = input._locale; } if (isDuration(input) && hasOwnProp(input, "_isValid")) { ret._isValid = input._isValid; } return ret; } createDuration.fn = Duration.prototype; createDuration.invalid = createInvalid$1; function parseIso(inp, sign3) { var res = inp && parseFloat(inp.replace(",", ".")); return (isNaN(res) ? 0 : res) * sign3; } function positiveMomentsDifference(base, other) { var res = {}; res.months = other.month() - base.month() + (other.year() - base.year()) * 12; if (base.clone().add(res.months, "M").isAfter(other)) { --res.months; } res.milliseconds = +other - +base.clone().add(res.months, "M"); return res; } function momentsDifference(base, other) { var res; if (!(base.isValid() && other.isValid())) { return { milliseconds: 0, months: 0 }; } other = cloneWithOffset(other, base); if (base.isBefore(other)) { res = positiveMomentsDifference(base, other); } else { res = positiveMomentsDifference(other, base); res.milliseconds = -res.milliseconds; res.months = -res.months; } return res; } function createAdder(direction, name) { return function(val, period) { var dur, tmp; if (period !== null && !isNaN(+period)) { deprecateSimple( name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info." ); tmp = val; val = period; period = tmp; } dur = createDuration(val, period); addSubtract(this, dur, direction); return this; }; } function addSubtract(mom, duration, isAdding, updateOffset) { var milliseconds2 = duration._milliseconds, days2 = absRound(duration._days), months2 = absRound(duration._months); if (!mom.isValid()) { return; } updateOffset = updateOffset == null ? true : updateOffset; if (months2) { setMonth(mom, get(mom, "Month") + months2 * isAdding); } if (days2) { set$1(mom, "Date", get(mom, "Date") + days2 * isAdding); } if (milliseconds2) { mom._d.setTime(mom._d.valueOf() + milliseconds2 * isAdding); } if (updateOffset) { hooks.updateOffset(mom, days2 || months2); } } var add = createAdder(1, "add"), subtract = createAdder(-1, "subtract"); function isString(input) { return typeof input === "string" || input instanceof String; } function isMomentInput(input) { return isMoment(input) || isDate(input) || isString(input) || isNumber2(input) || isNumberOrStringArray(input) || isMomentInputObject(input) || input === null || input === void 0; } function isMomentInputObject(input) { var objectTest = isObject2(input) && !isObjectEmpty(input), propertyTest = false, properties = [ "years", "year", "y", "months", "month", "M", "days", "day", "d", "dates", "date", "D", "hours", "hour", "h", "minutes", "minute", "m", "seconds", "second", "s", "milliseconds", "millisecond", "ms" ], i2, property, propertyLen = properties.length; for (i2 = 0; i2 < propertyLen; i2 += 1) { property = properties[i2]; propertyTest = propertyTest || hasOwnProp(input, property); } return objectTest && propertyTest; } function isNumberOrStringArray(input) { var arrayTest = isArray2(input), dataTypeTest = false; if (arrayTest) { dataTypeTest = input.filter(function(item) { return !isNumber2(item) && isString(input); }).length === 0; } return arrayTest && dataTypeTest; } function isCalendarSpec(input) { var objectTest = isObject2(input) && !isObjectEmpty(input), propertyTest = false, properties = [ "sameDay", "nextDay", "lastDay", "nextWeek", "lastWeek", "sameElse" ], i2, property; for (i2 = 0; i2 < properties.length; i2 += 1) { property = properties[i2]; propertyTest = propertyTest || hasOwnProp(input, property); } return objectTest && propertyTest; } function getCalendarFormat(myMoment, now3) { var diff2 = myMoment.diff(now3, "days", true); return diff2 < -6 ? "sameElse" : diff2 < -1 ? "lastWeek" : diff2 < 0 ? "lastDay" : diff2 < 1 ? "sameDay" : diff2 < 2 ? "nextDay" : diff2 < 7 ? "nextWeek" : "sameElse"; } function calendar$1(time, formats) { if (arguments.length === 1) { if (!arguments[0]) { time = void 0; formats = void 0; } else if (isMomentInput(arguments[0])) { time = arguments[0]; formats = void 0; } else if (isCalendarSpec(arguments[0])) { formats = arguments[0]; time = void 0; } } var now3 = time || createLocal(), sod = cloneWithOffset(now3, this).startOf("day"), format2 = hooks.calendarFormat(this, sod) || "sameElse", output = formats && (isFunction2(formats[format2]) ? formats[format2].call(this, now3) : formats[format2]); return this.format( output || this.localeData().calendar(format2, this, createLocal(now3)) ); } function clone3() { return new Moment3(this); } function isAfter(input, units) { var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || "millisecond"; if (units === "millisecond") { return this.valueOf() > localInput.valueOf(); } else { return localInput.valueOf() < this.clone().startOf(units).valueOf(); } } function isBefore(input, units) { var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || "millisecond"; if (units === "millisecond") { return this.valueOf() < localInput.valueOf(); } else { return this.clone().endOf(units).valueOf() < localInput.valueOf(); } } function isBetween(from3, to3, units, inclusivity) { var localFrom = isMoment(from3) ? from3 : createLocal(from3), localTo = isMoment(to3) ? to3 : createLocal(to3); if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { return false; } inclusivity = inclusivity || "()"; return (inclusivity[0] === "(" ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ")" ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); } function isSame(input, units) { var localInput = isMoment(input) ? input : createLocal(input), inputMs; if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || "millisecond"; if (units === "millisecond") { return this.valueOf() === localInput.valueOf(); } else { inputMs = localInput.valueOf(); return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); } } function isSameOrAfter(input, units) { return this.isSame(input, units) || this.isAfter(input, units); } function isSameOrBefore(input, units) { return this.isSame(input, units) || this.isBefore(input, units); } function diff(input, units, asFloat) { var that, zoneDelta, output; if (!this.isValid()) { return NaN; } that = cloneWithOffset(input, this); if (!that.isValid()) { return NaN; } zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; units = normalizeUnits(units); switch (units) { case "year": output = monthDiff(this, that) / 12; break; case "month": output = monthDiff(this, that); break; case "quarter": output = monthDiff(this, that) / 3; break; case "second": output = (this - that) / 1e3; break; // 1000 case "minute": output = (this - that) / 6e4; break; // 1000 * 60 case "hour": output = (this - that) / 36e5; break; // 1000 * 60 * 60 case "day": output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst case "week": output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst default: output = this - that; } return asFloat ? output : absFloor(output); } function monthDiff(a2, b2) { if (a2.date() < b2.date()) { return -monthDiff(b2, a2); } var wholeMonthDiff = (b2.year() - a2.year()) * 12 + (b2.month() - a2.month()), anchor = a2.clone().add(wholeMonthDiff, "months"), anchor2, adjust; if (b2 - anchor < 0) { anchor2 = a2.clone().add(wholeMonthDiff - 1, "months"); adjust = (b2 - anchor) / (anchor - anchor2); } else { anchor2 = a2.clone().add(wholeMonthDiff + 1, "months"); adjust = (b2 - anchor) / (anchor2 - anchor); } return -(wholeMonthDiff + adjust) || 0; } hooks.defaultFormat = "YYYY-MM-DDTHH:mm:ssZ"; hooks.defaultFormatUtc = "YYYY-MM-DDTHH:mm:ss[Z]"; function toString() { return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); } function toISOString(keepOffset) { if (!this.isValid()) { return null; } var utc = keepOffset !== true, m2 = utc ? this.clone().utc() : this; if (m2.year() < 0 || m2.year() > 9999) { return formatMoment( m2, utc ? "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYYYY-MM-DD[T]HH:mm:ss.SSSZ" ); } if (isFunction2(Date.prototype.toISOString)) { if (utc) { return this.toDate().toISOString(); } else { return new Date(this.valueOf() + this.utcOffset() * 60 * 1e3).toISOString().replace("Z", formatMoment(m2, "Z")); } } return formatMoment( m2, utc ? "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYY-MM-DD[T]HH:mm:ss.SSSZ" ); } function inspect() { if (!this.isValid()) { return "moment.invalid(/* " + this._i + " */)"; } var func = "moment", zone = "", prefix, year, datetime, suffix; if (!this.isLocal()) { func = this.utcOffset() === 0 ? "moment.utc" : "moment.parseZone"; zone = "Z"; } prefix = "[" + func + '("]'; year = 0 <= this.year() && this.year() <= 9999 ? "YYYY" : "YYYYYY"; datetime = "-MM-DD[T]HH:mm:ss.SSS"; suffix = zone + '[")]'; return this.format(prefix + year + datetime + suffix); } function format(inputString) { if (!inputString) { inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; } var output = formatMoment(this, inputString); return this.localeData().postformat(output); } function from2(time, withoutSuffix) { if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) { return createDuration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function fromNow(withoutSuffix) { return this.from(createLocal(), withoutSuffix); } function to2(time, withoutSuffix) { if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) { return createDuration({ from: this, to: time }).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function toNow(withoutSuffix) { return this.to(createLocal(), withoutSuffix); } function locale2(key) { var newLocaleData; if (key === void 0) { return this._locale._abbr; } else { newLocaleData = getLocale(key); if (newLocaleData != null) { this._locale = newLocaleData; } return this; } } var lang = deprecate( "moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.", function(key) { if (key === void 0) { return this.localeData(); } else { return this.locale(key); } } ); function localeData() { return this._locale; } var MS_PER_SECOND = 1e3, MS_PER_MINUTE = 60 * MS_PER_SECOND, MS_PER_HOUR = 60 * MS_PER_MINUTE, MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; function mod$1(dividend, divisor) { return (dividend % divisor + divisor) % divisor; } function localStartOfDate(y2, m2, d2) { if (y2 < 100 && y2 >= 0) { return new Date(y2 + 400, m2, d2) - MS_PER_400_YEARS; } else { return new Date(y2, m2, d2).valueOf(); } } function utcStartOfDate(y2, m2, d2) { if (y2 < 100 && y2 >= 0) { return Date.UTC(y2 + 400, m2, d2) - MS_PER_400_YEARS; } else { return Date.UTC(y2, m2, d2); } } function startOf(units) { var time, startOfDate; units = normalizeUnits(units); if (units === void 0 || units === "millisecond" || !this.isValid()) { return this; } startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; switch (units) { case "year": time = startOfDate(this.year(), 0, 1); break; case "quarter": time = startOfDate( this.year(), this.month() - this.month() % 3, 1 ); break; case "month": time = startOfDate(this.year(), this.month(), 1); break; case "week": time = startOfDate( this.year(), this.month(), this.date() - this.weekday() ); break; case "isoWeek": time = startOfDate( this.year(), this.month(), this.date() - (this.isoWeekday() - 1) ); break; case "day": case "date": time = startOfDate(this.year(), this.month(), this.date()); break; case "hour": time = this._d.valueOf(); time -= mod$1( time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR ); break; case "minute": time = this._d.valueOf(); time -= mod$1(time, MS_PER_MINUTE); break; case "second": time = this._d.valueOf(); time -= mod$1(time, MS_PER_SECOND); break; } this._d.setTime(time); hooks.updateOffset(this, true); return this; } function endOf(units) { var time, startOfDate; units = normalizeUnits(units); if (units === void 0 || units === "millisecond" || !this.isValid()) { return this; } startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; switch (units) { case "year": time = startOfDate(this.year() + 1, 0, 1) - 1; break; case "quarter": time = startOfDate( this.year(), this.month() - this.month() % 3 + 3, 1 ) - 1; break; case "month": time = startOfDate(this.year(), this.month() + 1, 1) - 1; break; case "week": time = startOfDate( this.year(), this.month(), this.date() - this.weekday() + 7 ) - 1; break; case "isoWeek": time = startOfDate( this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7 ) - 1; break; case "day": case "date": time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; break; case "hour": time = this._d.valueOf(); time += MS_PER_HOUR - mod$1( time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR ) - 1; break; case "minute": time = this._d.valueOf(); time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; break; case "second": time = this._d.valueOf(); time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; break; } this._d.setTime(time); hooks.updateOffset(this, true); return this; } function valueOf() { return this._d.valueOf() - (this._offset || 0) * 6e4; } function unix() { return Math.floor(this.valueOf() / 1e3); } function toDate() { return new Date(this.valueOf()); } function toArray() { var m2 = this; return [ m2.year(), m2.month(), m2.date(), m2.hour(), m2.minute(), m2.second(), m2.millisecond() ]; } function toObject() { var m2 = this; return { years: m2.year(), months: m2.month(), date: m2.date(), hours: m2.hours(), minutes: m2.minutes(), seconds: m2.seconds(), milliseconds: m2.milliseconds() }; } function toJSON() { return this.isValid() ? this.toISOString() : null; } function isValid$2() { return isValid(this); } function parsingFlags() { return extend({}, getParsingFlags(this)); } function invalidAt() { return getParsingFlags(this).overflow; } function creationData() { return { input: this._i, format: this._f, locale: this._locale, isUTC: this._isUTC, strict: this._strict }; } addFormatToken("N", 0, 0, "eraAbbr"); addFormatToken("NN", 0, 0, "eraAbbr"); addFormatToken("NNN", 0, 0, "eraAbbr"); addFormatToken("NNNN", 0, 0, "eraName"); addFormatToken("NNNNN", 0, 0, "eraNarrow"); addFormatToken("y", ["y", 1], "yo", "eraYear"); addFormatToken("y", ["yy", 2], 0, "eraYear"); addFormatToken("y", ["yyy", 3], 0, "eraYear"); addFormatToken("y", ["yyyy", 4], 0, "eraYear"); addRegexToken("N", matchEraAbbr); addRegexToken("NN", matchEraAbbr); addRegexToken("NNN", matchEraAbbr); addRegexToken("NNNN", matchEraName); addRegexToken("NNNNN", matchEraNarrow); addParseToken( ["N", "NN", "NNN", "NNNN", "NNNNN"], function(input, array, config, token2) { var era = config._locale.erasParse(input, token2, config._strict); if (era) { getParsingFlags(config).era = era; } else { getParsingFlags(config).invalidEra = input; } } ); addRegexToken("y", matchUnsigned); addRegexToken("yy", matchUnsigned); addRegexToken("yyy", matchUnsigned); addRegexToken("yyyy", matchUnsigned); addRegexToken("yo", matchEraYearOrdinal); addParseToken(["y", "yy", "yyy", "yyyy"], YEAR); addParseToken(["yo"], function(input, array, config, token2) { var match5; if (config._locale._eraYearOrdinalRegex) { match5 = input.match(config._locale._eraYearOrdinalRegex); } if (config._locale.eraYearOrdinalParse) { array[YEAR] = config._locale.eraYearOrdinalParse(input, match5); } else { array[YEAR] = parseInt(input, 10); } }); function localeEras(m2, format2) { var i2, l2, date, eras = this._eras || getLocale("en")._eras; for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { switch (typeof eras[i2].since) { case "string": date = hooks(eras[i2].since).startOf("day"); eras[i2].since = date.valueOf(); break; } switch (typeof eras[i2].until) { case "undefined": eras[i2].until = Infinity; break; case "string": date = hooks(eras[i2].until).startOf("day").valueOf(); eras[i2].until = date.valueOf(); break; } } return eras; } function localeErasParse(eraName, format2, strict) { var i2, l2, eras = this.eras(), name, abbr, narrow; eraName = eraName.toUpperCase(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { name = eras[i2].name.toUpperCase(); abbr = eras[i2].abbr.toUpperCase(); narrow = eras[i2].narrow.toUpperCase(); if (strict) { switch (format2) { case "N": case "NN": case "NNN": if (abbr === eraName) { return eras[i2]; } break; case "NNNN": if (name === eraName) { return eras[i2]; } break; case "NNNNN": if (narrow === eraName) { return eras[i2]; } break; } } else if ([name, abbr, narrow].indexOf(eraName) >= 0) { return eras[i2]; } } } function localeErasConvertYear(era, year) { var dir = era.since <= era.until ? 1 : -1; if (year === void 0) { return hooks(era.since).year(); } else { return hooks(era.since).year() + (year - era.offset) * dir; } } function getEraName() { var i2, l2, val, eras = this.localeData().eras(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { val = this.clone().startOf("day").valueOf(); if (eras[i2].since <= val && val <= eras[i2].until) { return eras[i2].name; } if (eras[i2].until <= val && val <= eras[i2].since) { return eras[i2].name; } } return ""; } function getEraNarrow() { var i2, l2, val, eras = this.localeData().eras(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { val = this.clone().startOf("day").valueOf(); if (eras[i2].since <= val && val <= eras[i2].until) { return eras[i2].narrow; } if (eras[i2].until <= val && val <= eras[i2].since) { return eras[i2].narrow; } } return ""; } function getEraAbbr() { var i2, l2, val, eras = this.localeData().eras(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { val = this.clone().startOf("day").valueOf(); if (eras[i2].since <= val && val <= eras[i2].until) { return eras[i2].abbr; } if (eras[i2].until <= val && val <= eras[i2].since) { return eras[i2].abbr; } } return ""; } function getEraYear() { var i2, l2, dir, val, eras = this.localeData().eras(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { dir = eras[i2].since <= eras[i2].until ? 1 : -1; val = this.clone().startOf("day").valueOf(); if (eras[i2].since <= val && val <= eras[i2].until || eras[i2].until <= val && val <= eras[i2].since) { return (this.year() - hooks(eras[i2].since).year()) * dir + eras[i2].offset; } } return this.year(); } function erasNameRegex(isStrict) { if (!hasOwnProp(this, "_erasNameRegex")) { computeErasParse.call(this); } return isStrict ? this._erasNameRegex : this._erasRegex; } function erasAbbrRegex(isStrict) { if (!hasOwnProp(this, "_erasAbbrRegex")) { computeErasParse.call(this); } return isStrict ? this._erasAbbrRegex : this._erasRegex; } function erasNarrowRegex(isStrict) { if (!hasOwnProp(this, "_erasNarrowRegex")) { computeErasParse.call(this); } return isStrict ? this._erasNarrowRegex : this._erasRegex; } function matchEraAbbr(isStrict, locale3) { return locale3.erasAbbrRegex(isStrict); } function matchEraName(isStrict, locale3) { return locale3.erasNameRegex(isStrict); } function matchEraNarrow(isStrict, locale3) { return locale3.erasNarrowRegex(isStrict); } function matchEraYearOrdinal(isStrict, locale3) { return locale3._eraYearOrdinalRegex || matchUnsigned; } function computeErasParse() { var abbrPieces = [], namePieces = [], narrowPieces = [], mixedPieces = [], i2, l2, erasName, erasAbbr, erasNarrow, eras = this.eras(); for (i2 = 0, l2 = eras.length; i2 < l2; ++i2) { erasName = regexEscape(eras[i2].name); erasAbbr = regexEscape(eras[i2].abbr); erasNarrow = regexEscape(eras[i2].narrow); namePieces.push(erasName); abbrPieces.push(erasAbbr); narrowPieces.push(erasNarrow); mixedPieces.push(erasName); mixedPieces.push(erasAbbr); mixedPieces.push(erasNarrow); } this._erasRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i"); this._erasNameRegex = new RegExp("^(" + namePieces.join("|") + ")", "i"); this._erasAbbrRegex = new RegExp("^(" + abbrPieces.join("|") + ")", "i"); this._erasNarrowRegex = new RegExp( "^(" + narrowPieces.join("|") + ")", "i" ); } addFormatToken(0, ["gg", 2], 0, function() { return this.weekYear() % 100; }); addFormatToken(0, ["GG", 2], 0, function() { return this.isoWeekYear() % 100; }); function addWeekYearFormatToken(token2, getter) { addFormatToken(0, [token2, token2.length], 0, getter); } addWeekYearFormatToken("gggg", "weekYear"); addWeekYearFormatToken("ggggg", "weekYear"); addWeekYearFormatToken("GGGG", "isoWeekYear"); addWeekYearFormatToken("GGGGG", "isoWeekYear"); addRegexToken("G", matchSigned); addRegexToken("g", matchSigned); addRegexToken("GG", match1to2, match2); addRegexToken("gg", match1to2, match2); addRegexToken("GGGG", match1to4, match4); addRegexToken("gggg", match1to4, match4); addRegexToken("GGGGG", match1to6, match6); addRegexToken("ggggg", match1to6, match6); addWeekParseToken( ["gggg", "ggggg", "GGGG", "GGGGG"], function(input, week, config, token2) { week[token2.substr(0, 2)] = toInt(input); } ); addWeekParseToken(["gg", "GG"], function(input, week, config, token2) { week[token2] = hooks.parseTwoDigitYear(input); }); function getSetWeekYear(input) { return getSetWeekYearHelper.call( this, input, this.week(), this.weekday() + this.localeData()._week.dow, this.localeData()._week.dow, this.localeData()._week.doy ); } function getSetISOWeekYear(input) { return getSetWeekYearHelper.call( this, input, this.isoWeek(), this.isoWeekday(), 1, 4 ); } function getISOWeeksInYear() { return weeksInYear(this.year(), 1, 4); } function getISOWeeksInISOWeekYear() { return weeksInYear(this.isoWeekYear(), 1, 4); } function getWeeksInYear() { var weekInfo = this.localeData()._week; return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); } function getWeeksInWeekYear() { var weekInfo = this.localeData()._week; return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy); } function getSetWeekYearHelper(input, week, weekday, dow, doy) { var weeksTarget; if (input == null) { return weekOfYear(this, dow, doy).year; } else { weeksTarget = weeksInYear(input, dow, doy); if (week > weeksTarget) { week = weeksTarget; } return setWeekAll.call(this, input, week, weekday, dow, doy); } } function setWeekAll(weekYear, week, weekday, dow, doy) { var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); this.year(date.getUTCFullYear()); this.month(date.getUTCMonth()); this.date(date.getUTCDate()); return this; } addFormatToken("Q", 0, "Qo", "quarter"); addRegexToken("Q", match1); addParseToken("Q", function(input, array) { array[MONTH] = (toInt(input) - 1) * 3; }); function getSetQuarter(input) { return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); } addFormatToken("D", ["DD", 2], "Do", "date"); addRegexToken("D", match1to2, match1to2NoLeadingZero); addRegexToken("DD", match1to2, match2); addRegexToken("Do", function(isStrict, locale3) { return isStrict ? locale3._dayOfMonthOrdinalParse || locale3._ordinalParse : locale3._dayOfMonthOrdinalParseLenient; }); addParseToken(["D", "DD"], DATE); addParseToken("Do", function(input, array) { array[DATE] = toInt(input.match(match1to2)[0]); }); var getSetDayOfMonth = makeGetSet("Date", true); addFormatToken("DDD", ["DDDD", 3], "DDDo", "dayOfYear"); addRegexToken("DDD", match1to3); addRegexToken("DDDD", match3); addParseToken(["DDD", "DDDD"], function(input, array, config) { config._dayOfYear = toInt(input); }); function getSetDayOfYear(input) { var dayOfYear = Math.round( (this.clone().startOf("day") - this.clone().startOf("year")) / 864e5 ) + 1; return input == null ? dayOfYear : this.add(input - dayOfYear, "d"); } addFormatToken("m", ["mm", 2], 0, "minute"); addRegexToken("m", match1to2, match1to2HasZero); addRegexToken("mm", match1to2, match2); addParseToken(["m", "mm"], MINUTE); var getSetMinute = makeGetSet("Minutes", false); addFormatToken("s", ["ss", 2], 0, "second"); addRegexToken("s", match1to2, match1to2HasZero); addRegexToken("ss", match1to2, match2); addParseToken(["s", "ss"], SECOND); var getSetSecond = makeGetSet("Seconds", false); addFormatToken("S", 0, 0, function() { return ~~(this.millisecond() / 100); }); addFormatToken(0, ["SS", 2], 0, function() { return ~~(this.millisecond() / 10); }); addFormatToken(0, ["SSS", 3], 0, "millisecond"); addFormatToken(0, ["SSSS", 4], 0, function() { return this.millisecond() * 10; }); addFormatToken(0, ["SSSSS", 5], 0, function() { return this.millisecond() * 100; }); addFormatToken(0, ["SSSSSS", 6], 0, function() { return this.millisecond() * 1e3; }); addFormatToken(0, ["SSSSSSS", 7], 0, function() { return this.millisecond() * 1e4; }); addFormatToken(0, ["SSSSSSSS", 8], 0, function() { return this.millisecond() * 1e5; }); addFormatToken(0, ["SSSSSSSSS", 9], 0, function() { return this.millisecond() * 1e6; }); addRegexToken("S", match1to3, match1); addRegexToken("SS", match1to3, match2); addRegexToken("SSS", match1to3, match3); var token, getSetMillisecond; for (token = "SSSS"; token.length <= 9; token += "S") { addRegexToken(token, matchUnsigned); } function parseMs(input, array) { array[MILLISECOND] = toInt(("0." + input) * 1e3); } for (token = "S"; token.length <= 9; token += "S") { addParseToken(token, parseMs); } getSetMillisecond = makeGetSet("Milliseconds", false); addFormatToken("z", 0, 0, "zoneAbbr"); addFormatToken("zz", 0, 0, "zoneName"); function getZoneAbbr() { return this._isUTC ? "UTC" : ""; } function getZoneName() { return this._isUTC ? "Coordinated Universal Time" : ""; } var proto = Moment3.prototype; proto.add = add; proto.calendar = calendar$1; proto.clone = clone3; proto.diff = diff; proto.endOf = endOf; proto.format = format; proto.from = from2; proto.fromNow = fromNow; proto.to = to2; proto.toNow = toNow; proto.get = stringGet; proto.invalidAt = invalidAt; proto.isAfter = isAfter; proto.isBefore = isBefore; proto.isBetween = isBetween; proto.isSame = isSame; proto.isSameOrAfter = isSameOrAfter; proto.isSameOrBefore = isSameOrBefore; proto.isValid = isValid$2; proto.lang = lang; proto.locale = locale2; proto.localeData = localeData; proto.max = prototypeMax; proto.min = prototypeMin; proto.parsingFlags = parsingFlags; proto.set = stringSet; proto.startOf = startOf; proto.subtract = subtract; proto.toArray = toArray; proto.toObject = toObject; proto.toDate = toDate; proto.toISOString = toISOString; proto.inspect = inspect; if (typeof Symbol !== "undefined" && Symbol.for != null) { proto[Symbol.for("nodejs.util.inspect.custom")] = function() { return "Moment<" + this.format() + ">"; }; } proto.toJSON = toJSON; proto.toString = toString; proto.unix = unix; proto.valueOf = valueOf; proto.creationData = creationData; proto.eraName = getEraName; proto.eraNarrow = getEraNarrow; proto.eraAbbr = getEraAbbr; proto.eraYear = getEraYear; proto.year = getSetYear; proto.isLeapYear = getIsLeapYear; proto.weekYear = getSetWeekYear; proto.isoWeekYear = getSetISOWeekYear; proto.quarter = proto.quarters = getSetQuarter; proto.month = getSetMonth; proto.daysInMonth = getDaysInMonth; proto.week = proto.weeks = getSetWeek; proto.isoWeek = proto.isoWeeks = getSetISOWeek; proto.weeksInYear = getWeeksInYear; proto.weeksInWeekYear = getWeeksInWeekYear; proto.isoWeeksInYear = getISOWeeksInYear; proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear; proto.date = getSetDayOfMonth; proto.day = proto.days = getSetDayOfWeek; proto.weekday = getSetLocaleDayOfWeek; proto.isoWeekday = getSetISODayOfWeek; proto.dayOfYear = getSetDayOfYear; proto.hour = proto.hours = getSetHour; proto.minute = proto.minutes = getSetMinute; proto.second = proto.seconds = getSetSecond; proto.millisecond = proto.milliseconds = getSetMillisecond; proto.utcOffset = getSetOffset; proto.utc = setOffsetToUTC; proto.local = setOffsetToLocal; proto.parseZone = setOffsetToParsedOffset; proto.hasAlignedHourOffset = hasAlignedHourOffset; proto.isDST = isDaylightSavingTime; proto.isLocal = isLocal; proto.isUtcOffset = isUtcOffset; proto.isUtc = isUtc; proto.isUTC = isUtc; proto.zoneAbbr = getZoneAbbr; proto.zoneName = getZoneName; proto.dates = deprecate( "dates accessor is deprecated. Use date instead.", getSetDayOfMonth ); proto.months = deprecate( "months accessor is deprecated. Use month instead", getSetMonth ); proto.years = deprecate( "years accessor is deprecated. Use year instead", getSetYear ); proto.zone = deprecate( "moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/", getSetZone ); proto.isDSTShifted = deprecate( "isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information", isDaylightSavingTimeShifted ); function createUnix(input) { return createLocal(input * 1e3); } function createInZone() { return createLocal.apply(null, arguments).parseZone(); } function preParsePostFormat(string) { return string; } var proto$1 = Locale.prototype; proto$1.calendar = calendar; proto$1.longDateFormat = longDateFormat; proto$1.invalidDate = invalidDate; proto$1.ordinal = ordinal; proto$1.preparse = preParsePostFormat; proto$1.postformat = preParsePostFormat; proto$1.relativeTime = relativeTime; proto$1.pastFuture = pastFuture; proto$1.set = set2; proto$1.eras = localeEras; proto$1.erasParse = localeErasParse; proto$1.erasConvertYear = localeErasConvertYear; proto$1.erasAbbrRegex = erasAbbrRegex; proto$1.erasNameRegex = erasNameRegex; proto$1.erasNarrowRegex = erasNarrowRegex; proto$1.months = localeMonths; proto$1.monthsShort = localeMonthsShort; proto$1.monthsParse = localeMonthsParse; proto$1.monthsRegex = monthsRegex; proto$1.monthsShortRegex = monthsShortRegex; proto$1.week = localeWeek; proto$1.firstDayOfYear = localeFirstDayOfYear; proto$1.firstDayOfWeek = localeFirstDayOfWeek; proto$1.weekdays = localeWeekdays; proto$1.weekdaysMin = localeWeekdaysMin; proto$1.weekdaysShort = localeWeekdaysShort; proto$1.weekdaysParse = localeWeekdaysParse; proto$1.weekdaysRegex = weekdaysRegex; proto$1.weekdaysShortRegex = weekdaysShortRegex; proto$1.weekdaysMinRegex = weekdaysMinRegex; proto$1.isPM = localeIsPM; proto$1.meridiem = localeMeridiem; function get$1(format2, index, field, setter) { var locale3 = getLocale(), utc = createUTC().set(setter, index); return locale3[field](utc, format2); } function listMonthsImpl(format2, index, field) { if (isNumber2(format2)) { index = format2; format2 = void 0; } format2 = format2 || ""; if (index != null) { return get$1(format2, index, field, "month"); } var i2, out = []; for (i2 = 0; i2 < 12; i2++) { out[i2] = get$1(format2, i2, field, "month"); } return out; } function listWeekdaysImpl(localeSorted, format2, index, field) { if (typeof localeSorted === "boolean") { if (isNumber2(format2)) { index = format2; format2 = void 0; } format2 = format2 || ""; } else { format2 = localeSorted; index = format2; localeSorted = false; if (isNumber2(format2)) { index = format2; format2 = void 0; } format2 = format2 || ""; } var locale3 = getLocale(), shift = localeSorted ? locale3._week.dow : 0, i2, out = []; if (index != null) { return get$1(format2, (index + shift) % 7, field, "day"); } for (i2 = 0; i2 < 7; i2++) { out[i2] = get$1(format2, (i2 + shift) % 7, field, "day"); } return out; } function listMonths(format2, index) { return listMonthsImpl(format2, index, "months"); } function listMonthsShort(format2, index) { return listMonthsImpl(format2, index, "monthsShort"); } function listWeekdays(localeSorted, format2, index) { return listWeekdaysImpl(localeSorted, format2, index, "weekdays"); } function listWeekdaysShort(localeSorted, format2, index) { return listWeekdaysImpl(localeSorted, format2, index, "weekdaysShort"); } function listWeekdaysMin(localeSorted, format2, index) { return listWeekdaysImpl(localeSorted, format2, index, "weekdaysMin"); } getSetGlobalLocale("en", { eras: [ { since: "0001-01-01", until: Infinity, offset: 1, name: "Anno Domini", narrow: "AD", abbr: "AD" }, { since: "0000-12-31", until: -Infinity, offset: 1, name: "Before Christ", narrow: "BC", abbr: "BC" } ], dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: function(number) { var b2 = number % 10, output = toInt(number % 100 / 10) === 1 ? "th" : b2 === 1 ? "st" : b2 === 2 ? "nd" : b2 === 3 ? "rd" : "th"; return number + output; } }); hooks.lang = deprecate( "moment.lang is deprecated. Use moment.locale instead.", getSetGlobalLocale ); hooks.langData = deprecate( "moment.langData is deprecated. Use moment.localeData instead.", getLocale ); var mathAbs = Math.abs; function abs() { var data = this._data; this._milliseconds = mathAbs(this._milliseconds); this._days = mathAbs(this._days); this._months = mathAbs(this._months); data.milliseconds = mathAbs(data.milliseconds); data.seconds = mathAbs(data.seconds); data.minutes = mathAbs(data.minutes); data.hours = mathAbs(data.hours); data.months = mathAbs(data.months); data.years = mathAbs(data.years); return this; } function addSubtract$1(duration, input, value, direction) { var other = createDuration(input, value); duration._milliseconds += direction * other._milliseconds; duration._days += direction * other._days; duration._months += direction * other._months; return duration._bubble(); } function add$1(input, value) { return addSubtract$1(this, input, value, 1); } function subtract$1(input, value) { return addSubtract$1(this, input, value, -1); } function absCeil(number) { if (number < 0) { return Math.floor(number); } else { return Math.ceil(number); } } function bubble() { var milliseconds2 = this._milliseconds, days2 = this._days, months2 = this._months, data = this._data, seconds2, minutes2, hours2, years2, monthsFromDays; if (!(milliseconds2 >= 0 && days2 >= 0 && months2 >= 0 || milliseconds2 <= 0 && days2 <= 0 && months2 <= 0)) { milliseconds2 += absCeil(monthsToDays(months2) + days2) * 864e5; days2 = 0; months2 = 0; } data.milliseconds = milliseconds2 % 1e3; seconds2 = absFloor(milliseconds2 / 1e3); data.seconds = seconds2 % 60; minutes2 = absFloor(seconds2 / 60); data.minutes = minutes2 % 60; hours2 = absFloor(minutes2 / 60); data.hours = hours2 % 24; days2 += absFloor(hours2 / 24); monthsFromDays = absFloor(daysToMonths(days2)); months2 += monthsFromDays; days2 -= absCeil(monthsToDays(monthsFromDays)); years2 = absFloor(months2 / 12); months2 %= 12; data.days = days2; data.months = months2; data.years = years2; return this; } function daysToMonths(days2) { return days2 * 4800 / 146097; } function monthsToDays(months2) { return months2 * 146097 / 4800; } function as(units) { if (!this.isValid()) { return NaN; } var days2, months2, milliseconds2 = this._milliseconds; units = normalizeUnits(units); if (units === "month" || units === "quarter" || units === "year") { days2 = this._days + milliseconds2 / 864e5; months2 = this._months + daysToMonths(days2); switch (units) { case "month": return months2; case "quarter": return months2 / 3; case "year": return months2 / 12; } } else { days2 = this._days + Math.round(monthsToDays(this._months)); switch (units) { case "week": return days2 / 7 + milliseconds2 / 6048e5; case "day": return days2 + milliseconds2 / 864e5; case "hour": return days2 * 24 + milliseconds2 / 36e5; case "minute": return days2 * 1440 + milliseconds2 / 6e4; case "second": return days2 * 86400 + milliseconds2 / 1e3; // Math.floor prevents floating point math errors here case "millisecond": return Math.floor(days2 * 864e5) + milliseconds2; default: throw new Error("Unknown unit " + units); } } } function makeAs(alias) { return function() { return this.as(alias); }; } var asMilliseconds = makeAs("ms"), asSeconds = makeAs("s"), asMinutes = makeAs("m"), asHours = makeAs("h"), asDays = makeAs("d"), asWeeks = makeAs("w"), asMonths = makeAs("M"), asQuarters = makeAs("Q"), asYears = makeAs("y"), valueOf$1 = asMilliseconds; function clone$1() { return createDuration(this); } function get$2(units) { units = normalizeUnits(units); return this.isValid() ? this[units + "s"]() : NaN; } function makeGetter(name) { return function() { return this.isValid() ? this._data[name] : NaN; }; } var milliseconds = makeGetter("milliseconds"), seconds = makeGetter("seconds"), minutes = makeGetter("minutes"), hours = makeGetter("hours"), days = makeGetter("days"), months = makeGetter("months"), years = makeGetter("years"); function weeks() { return absFloor(this.days() / 7); } var round2 = Math.round, thresholds = { ss: 44, // a few seconds to seconds s: 45, // seconds to minute m: 45, // minutes to hour h: 22, // hours to day d: 26, // days to month/week w: null, // weeks to month M: 11 // months to year }; function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale3) { return locale3.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } function relativeTime$1(posNegDuration, withoutSuffix, thresholds2, locale3) { var duration = createDuration(posNegDuration).abs(), seconds2 = round2(duration.as("s")), minutes2 = round2(duration.as("m")), hours2 = round2(duration.as("h")), days2 = round2(duration.as("d")), months2 = round2(duration.as("M")), weeks2 = round2(duration.as("w")), years2 = round2(duration.as("y")), a2 = seconds2 <= thresholds2.ss && ["s", seconds2] || seconds2 < thresholds2.s && ["ss", seconds2] || minutes2 <= 1 && ["m"] || minutes2 < thresholds2.m && ["mm", minutes2] || hours2 <= 1 && ["h"] || hours2 < thresholds2.h && ["hh", hours2] || days2 <= 1 && ["d"] || days2 < thresholds2.d && ["dd", days2]; if (thresholds2.w != null) { a2 = a2 || weeks2 <= 1 && ["w"] || weeks2 < thresholds2.w && ["ww", weeks2]; } a2 = a2 || months2 <= 1 && ["M"] || months2 < thresholds2.M && ["MM", months2] || years2 <= 1 && ["y"] || ["yy", years2]; a2[2] = withoutSuffix; a2[3] = +posNegDuration > 0; a2[4] = locale3; return substituteTimeAgo.apply(null, a2); } function getSetRelativeTimeRounding(roundingFunction) { if (roundingFunction === void 0) { return round2; } if (typeof roundingFunction === "function") { round2 = roundingFunction; return true; } return false; } function getSetRelativeTimeThreshold(threshold, limit) { if (thresholds[threshold] === void 0) { return false; } if (limit === void 0) { return thresholds[threshold]; } thresholds[threshold] = limit; if (threshold === "s") { thresholds.ss = limit - 1; } return true; } function humanize(argWithSuffix, argThresholds) { if (!this.isValid()) { return this.localeData().invalidDate(); } var withSuffix = false, th = thresholds, locale3, output; if (typeof argWithSuffix === "object") { argThresholds = argWithSuffix; argWithSuffix = false; } if (typeof argWithSuffix === "boolean") { withSuffix = argWithSuffix; } if (typeof argThresholds === "object") { th = Object.assign({}, thresholds, argThresholds); if (argThresholds.s != null && argThresholds.ss == null) { th.ss = argThresholds.s - 1; } } locale3 = this.localeData(); output = relativeTime$1(this, !withSuffix, th, locale3); if (withSuffix) { output = locale3.pastFuture(+this, output); } return locale3.postformat(output); } var abs$1 = Math.abs; function sign2(x2) { return (x2 > 0) - (x2 < 0) || +x2; } function toISOString$1() { if (!this.isValid()) { return this.localeData().invalidDate(); } var seconds2 = abs$1(this._milliseconds) / 1e3, days2 = abs$1(this._days), months2 = abs$1(this._months), minutes2, hours2, years2, s2, total = this.asSeconds(), totalSign, ymSign, daysSign, hmsSign; if (!total) { return "P0D"; } minutes2 = absFloor(seconds2 / 60); hours2 = absFloor(minutes2 / 60); seconds2 %= 60; minutes2 %= 60; years2 = absFloor(months2 / 12); months2 %= 12; s2 = seconds2 ? seconds2.toFixed(3).replace(/\.?0+$/, "") : ""; totalSign = total < 0 ? "-" : ""; ymSign = sign2(this._months) !== sign2(total) ? "-" : ""; daysSign = sign2(this._days) !== sign2(total) ? "-" : ""; hmsSign = sign2(this._milliseconds) !== sign2(total) ? "-" : ""; return totalSign + "P" + (years2 ? ymSign + years2 + "Y" : "") + (months2 ? ymSign + months2 + "M" : "") + (days2 ? daysSign + days2 + "D" : "") + (hours2 || minutes2 || seconds2 ? "T" : "") + (hours2 ? hmsSign + hours2 + "H" : "") + (minutes2 ? hmsSign + minutes2 + "M" : "") + (seconds2 ? hmsSign + s2 + "S" : ""); } var proto$2 = Duration.prototype; proto$2.isValid = isValid$1; proto$2.abs = abs; proto$2.add = add$1; proto$2.subtract = subtract$1; proto$2.as = as; proto$2.asMilliseconds = asMilliseconds; proto$2.asSeconds = asSeconds; proto$2.asMinutes = asMinutes; proto$2.asHours = asHours; proto$2.asDays = asDays; proto$2.asWeeks = asWeeks; proto$2.asMonths = asMonths; proto$2.asQuarters = asQuarters; proto$2.asYears = asYears; proto$2.valueOf = valueOf$1; proto$2._bubble = bubble; proto$2.clone = clone$1; proto$2.get = get$2; proto$2.milliseconds = milliseconds; proto$2.seconds = seconds; proto$2.minutes = minutes; proto$2.hours = hours; proto$2.days = days; proto$2.weeks = weeks; proto$2.months = months; proto$2.years = years; proto$2.humanize = humanize; proto$2.toISOString = toISOString$1; proto$2.toString = toISOString$1; proto$2.toJSON = toISOString$1; proto$2.locale = locale2; proto$2.localeData = localeData; proto$2.toIsoString = deprecate( "toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)", toISOString$1 ); proto$2.lang = lang; addFormatToken("X", 0, 0, "unix"); addFormatToken("x", 0, 0, "valueOf"); addRegexToken("x", matchSigned); addRegexToken("X", matchTimestamp); addParseToken("X", function(input, array, config) { config._d = new Date(parseFloat(input) * 1e3); }); addParseToken("x", function(input, array, config) { config._d = new Date(toInt(input)); }); hooks.version = "2.30.1"; setHookCallback(createLocal); hooks.fn = proto; hooks.min = min; hooks.max = max; hooks.now = now2; hooks.utc = createUTC; hooks.unix = createUnix; hooks.months = listMonths; hooks.isDate = isDate; hooks.locale = getSetGlobalLocale; hooks.invalid = createInvalid; hooks.duration = createDuration; hooks.isMoment = isMoment; hooks.weekdays = listWeekdays; hooks.parseZone = createInZone; hooks.localeData = getLocale; hooks.isDuration = isDuration; hooks.monthsShort = listMonthsShort; hooks.weekdaysMin = listWeekdaysMin; hooks.defineLocale = defineLocale; hooks.updateLocale = updateLocale; hooks.locales = listLocales; hooks.weekdaysShort = listWeekdaysShort; hooks.normalizeUnits = normalizeUnits; hooks.relativeTimeRounding = getSetRelativeTimeRounding; hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; hooks.calendarFormat = getCalendarFormat; hooks.prototype = proto; hooks.HTML5_FMT = { DATETIME_LOCAL: "YYYY-MM-DDTHH:mm", // DATETIME_LOCAL_SECONDS: "YYYY-MM-DDTHH:mm:ss", // DATETIME_LOCAL_MS: "YYYY-MM-DDTHH:mm:ss.SSS", // DATE: "YYYY-MM-DD", // TIME: "HH:mm", // TIME_SECONDS: "HH:mm:ss", // TIME_MS: "HH:mm:ss.SSS", // WEEK: "GGGG-[W]WW", // MONTH: "YYYY-MM" // }; return hooks; }); } }); // node_modules/.pnpm/pagerank.js@1.0.2/node_modules/pagerank.js/lib/index.js var require_lib = __commonJS({ "node_modules/.pnpm/pagerank.js@1.0.2/node_modules/pagerank.js/lib/index.js"(exports, module2) { "use strict"; function forOwn(object, callback2) { if (typeof object === "object" && typeof callback2 === "function") { for (var key in object) { if (object.hasOwnProperty(key) === true) { if (callback2(key, object[key]) === false) { break; } } } } } module2.exports = function() { var self = { count: 0, edges: {}, nodes: {} }; self.link = function(source, target, weight) { if (isFinite(weight) !== true || weight === null) { weight = 1; } weight = parseFloat(weight); if (self.nodes.hasOwnProperty(source) !== true) { self.count++; self.nodes[source] = { weight: 0, outbound: 0 }; } self.nodes[source].outbound += weight; if (self.nodes.hasOwnProperty(target) !== true) { self.count++; self.nodes[target] = { weight: 0, outbound: 0 }; } if (self.edges.hasOwnProperty(source) !== true) { self.edges[source] = {}; } if (self.edges[source].hasOwnProperty(target) !== true) { self.edges[source][target] = 0; } self.edges[source][target] += weight; }; self.rank = function(alpha2, epsilon, callback2) { var delta = 1, inverse = 1 / self.count; forOwn(self.edges, function(source) { if (self.nodes[source].outbound > 0) { forOwn(self.edges[source], function(target) { self.edges[source][target] /= self.nodes[source].outbound; }); } }); forOwn(self.nodes, function(key) { self.nodes[key].weight = inverse; }); while (delta > epsilon) { var leak = 0, nodes = {}; forOwn(self.nodes, function(key, value) { nodes[key] = value.weight; if (value.outbound === 0) { leak += value.weight; } self.nodes[key].weight = 0; }); leak *= alpha2; forOwn(self.nodes, function(source) { forOwn(self.edges[source], function(target, weight) { self.nodes[target].weight += alpha2 * nodes[source] * weight; }); self.nodes[source].weight += (1 - alpha2) * inverse + leak * inverse; }); delta = 0; forOwn(self.nodes, function(key, value) { delta += Math.abs(value.weight - nodes[key]); }); } forOwn(self.nodes, function(key) { return callback2(key, self.nodes[key].weight); }); }; self.reset = function() { self.count = 0; self.edges = {}; self.nodes = {}; }; return self; }(); } }); // node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js var require_balanced_match = __commonJS({ "node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js"(exports, module2) { "use strict"; module2.exports = balanced; function balanced(a2, b2, str) { if (a2 instanceof RegExp) a2 = maybeMatch(a2, str); if (b2 instanceof RegExp) b2 = maybeMatch(b2, str); var r2 = range(a2, b2, str); return r2 && { start: r2[0], end: r2[1], pre: str.slice(0, r2[0]), body: str.slice(r2[0] + a2.length, r2[1]), post: str.slice(r2[1] + b2.length) }; } function maybeMatch(reg, str) { var m2 = str.match(reg); return m2 ? m2[0] : null; } balanced.range = range; function range(a2, b2, str) { var begs, beg, left, right, result; var ai = str.indexOf(a2); var bi = str.indexOf(b2, ai + 1); var i2 = ai; if (ai >= 0 && bi > 0) { if (a2 === b2) { return [ai, bi]; } begs = []; left = str.length; while (i2 >= 0 && !result) { if (i2 == ai) { begs.push(i2); ai = str.indexOf(a2, i2 + 1); } else if (begs.length == 1) { result = [begs.pop(), bi]; } else { beg = begs.pop(); if (beg < left) { left = beg; right = bi; } bi = str.indexOf(b2, i2 + 1); } i2 = ai < bi && ai >= 0 ? ai : bi; } if (begs.length) { result = [left, right]; } } return result; } } }); // node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js var require_brace_expansion = __commonJS({ "node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js"(exports, module2) { var balanced = require_balanced_match(); module2.exports = expandTop; var escSlash = "\0SLASH" + Math.random() + "\0"; var escOpen = "\0OPEN" + Math.random() + "\0"; var escClose = "\0CLOSE" + Math.random() + "\0"; var escComma = "\0COMMA" + Math.random() + "\0"; var escPeriod = "\0PERIOD" + Math.random() + "\0"; function numeric(str) { return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); } function escapeBraces(str) { return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod); } function unescapeBraces(str) { return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join("."); } function parseCommaParts(str) { if (!str) return [""]; var parts = []; var m2 = balanced("{", "}", str); if (!m2) return str.split(","); var pre = m2.pre; var body = m2.body; var post = m2.post; var p2 = pre.split(","); p2[p2.length - 1] += "{" + body + "}"; var postParts = parseCommaParts(post); if (post.length) { p2[p2.length - 1] += postParts.shift(); p2.push.apply(p2, postParts); } parts.push.apply(parts, p2); return parts; } function expandTop(str) { if (!str) return []; if (str.substr(0, 2) === "{}") { str = "\\{\\}" + str.substr(2); } return expand2(escapeBraces(str), true).map(unescapeBraces); } function embrace(str) { return "{" + str + "}"; } function isPadded(el) { return /^-?0\d/.test(el); } function lte(i2, y2) { return i2 <= y2; } function gte(i2, y2) { return i2 >= y2; } function expand2(str, isTop) { var expansions = []; var m2 = balanced("{", "}", str); if (!m2) return [str]; var pre = m2.pre; var post = m2.post.length ? expand2(m2.post, false) : [""]; if (/\$$/.test(m2.pre)) { for (var k = 0; k < post.length; k++) { var expansion = pre + "{" + m2.body + "}" + post[k]; expansions.push(expansion); } } else { var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m2.body); var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m2.body); var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m2.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { if (m2.post.match(/,.*\}/)) { str = m2.pre + "{" + m2.body + escClose + m2.post; return expand2(str); } return [str]; } var n2; if (isSequence) { n2 = m2.body.split(/\.\./); } else { n2 = parseCommaParts(m2.body); if (n2.length === 1) { n2 = expand2(n2[0], false).map(embrace); if (n2.length === 1) { return post.map(function(p2) { return m2.pre + n2[0] + p2; }); } } } var N2; if (isSequence) { var x2 = numeric(n2[0]); var y2 = numeric(n2[1]); var width = Math.max(n2[0].length, n2[1].length); var incr = n2.length == 3 ? Math.abs(numeric(n2[2])) : 1; var test = lte; var reverse = y2 < x2; if (reverse) { incr *= -1; test = gte; } var pad = n2.some(isPadded); N2 = []; for (var i2 = x2; test(i2, y2); i2 += incr) { var c2; if (isAlphaSequence) { c2 = String.fromCharCode(i2); if (c2 === "\\") c2 = ""; } else { c2 = String(i2); if (pad) { var need = width - c2.length; if (need > 0) { var z2 = new Array(need + 1).join("0"); if (i2 < 0) c2 = "-" + z2 + c2.slice(1); else c2 = z2 + c2; } } } N2.push(c2); } } else { N2 = []; for (var j2 = 0; j2 < n2.length; j2++) { N2.push.apply(N2, expand2(n2[j2], false)); } } for (var j2 = 0; j2 < N2.length; j2++) { for (var k = 0; k < post.length; k++) { var expansion = pre + N2[j2] + post[k]; if (!isTop || isSequence || expansion) expansions.push(expansion); } } } return expansions; } } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/utils.js var require_utils = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/utils.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.simpleFormatter = exports.htmlFormatter = exports.escapeRegexString = void 0; function escapeRegexString(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } exports.escapeRegexString = escapeRegexString; var htmlFormatter = class { asking(answer, hint) { return `${!hint ? "[...]" : `[${hint}]`}`; } showingAnswer(answer, hint) { return `${answer}`; } hiding(answer, hint) { return `${!hint ? "..." : `[${hint}]`} `; } }; exports.htmlFormatter = htmlFormatter; var simpleFormatter = class { asking(answer, hint) { return `${!hint ? "[...]" : `[${hint}]`}`; } showingAnswer(answer, hint) { return answer; } hiding(answer, hint) { return `...`; } }; exports.simpleFormatter = simpleFormatter; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeFieldEnum.js var require_ClozeFieldEnum = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeFieldEnum.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeFieldEnum = void 0; var ClozeFieldEnum; (function(ClozeFieldEnum2) { ClozeFieldEnum2["seq"] = "seq"; ClozeFieldEnum2["answer"] = "answer"; ClozeFieldEnum2["hint"] = "hint"; })(ClozeFieldEnum || (exports.ClozeFieldEnum = ClozeFieldEnum = {})); } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeRegExp.js var require_ClozeRegExp = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeRegExp.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeRegExp = void 0; var ClozeFieldEnum_1 = require_ClozeFieldEnum(); var ClozeRegExp = class { constructor(pattern, clozeFieldsOrder, flags) { this.regex = new RegExp(pattern, flags); this.clozeFieldsOrder = clozeFieldsOrder; } exec(str) { let match2 = this.regex.exec(str); if (!match2) { return null; } if (this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.answer) == -1) { throw new Error("Cloze text not found in clozeFieldsOrder"); } if (this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.hint) == -1) { throw new Error("Cloze hint not found in clozeFieldsOrder"); } if (this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.seq) == -1) { match2.seq = null; } else { match2.seq = match2[this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.seq) + 1]; } match2.raw = match2[0]; match2.answer = match2[this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.answer) + 1]; match2.hint = match2[this.clozeFieldsOrder.indexOf(ClozeFieldEnum_1.ClozeFieldEnum.hint) + 1]; return match2; } test(str) { return this.regex.test(str); } }; exports.ClozeRegExp = ClozeRegExp; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNote.js var require_ClozeNote = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNote.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeNote = void 0; var ClozeNote = class { /** * Creates a new ClozeNote instance. * * @param raw The raw text of the cloze note before processing. */ constructor(raw, patterns) { this._raw = raw; const { clozeDeletions, numCards } = this.initParsing(raw, patterns); this._clozeDeletions = clozeDeletions; this._numCards = numCards; } get raw() { return this._raw; } get numCards() { return this._numCards; } }; exports.ClozeNote = ClozeNote; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteClassic.js var require_ClozeNoteClassic = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteClassic.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeNoteClassic = void 0; var ClozeNote_1 = require_ClozeNote(); var utils_1 = require_utils(); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); var ClozeNoteClassic = class extends ClozeNote_1.ClozeNote { constructor(raw, patterns) { super(raw, patterns); } get clozeType() { return ClozeTypeEnum_1.ClozeTypeEnum.CLASSIC; } initParsing(rawNote, patterns) { let clozeDeletions = []; let numCards = 0; patterns.forEach((pattern) => { const regex = pattern.getClozeRegex(ClozeTypeEnum_1.ClozeTypeEnum.CLASSIC); let match2; while (match2 = regex.exec(rawNote)) { if (!match2.seq) { break; } let newCloze = { raw: match2.raw, answer: match2.answer, seq: parseInt(match2.seq), hint: match2.hint }; clozeDeletions.push(newCloze); if (numCards < newCloze.seq) { numCards = newCloze.seq; } } }); return { clozeDeletions, numCards }; } getCardFront(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let frontText = this.raw; for (const deletion of this._clozeDeletions) { if (deletion.seq !== cardIndex + 1) { frontText = frontText.replace(deletion.raw, deletion.answer); continue; } frontText = frontText.replace(deletion.raw, formatter.asking(deletion.answer, deletion.hint)); } return frontText; } getCardBack(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let backText = this.raw; for (const deletion of this._clozeDeletions) { if (deletion.seq === cardIndex + 1) { backText = backText.replace(deletion.raw, formatter.showingAnswer(deletion.answer, deletion.hint)); } else { backText = backText.replace(deletion.raw, deletion.answer); } } return backText; } }; exports.ClozeNoteClassic = ClozeNoteClassic; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteOL.js var require_ClozeNoteOL = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteOL.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeNoteOL = void 0; var ClozeNote_1 = require_ClozeNote(); var utils_1 = require_utils(); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); var ClozeNoteOL = class extends ClozeNote_1.ClozeNote { constructor(raw, patterns) { super(raw, patterns); } get clozeType() { return ClozeTypeEnum_1.ClozeTypeEnum.OVERLAPPING; } initParsing(rawNote, patterns) { let clozeDeletions = []; let numCards = 0; patterns.forEach((pattern) => { const regex = pattern.getClozeRegex(ClozeTypeEnum_1.ClozeTypeEnum.OVERLAPPING); let match2; while (match2 = regex.exec(rawNote)) { if (!match2.seq) { break; } let newCloze = { raw: match2.raw, answer: match2.answer, seq: match2.seq, hint: match2.hint }; clozeDeletions.push(newCloze); if (numCards < newCloze.seq.length) { numCards = newCloze.seq.length; } } }); return { clozeDeletions, numCards }; } getCardFront(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let frontText = this.raw; for (const deletion of this._clozeDeletions) { let clozeAction = "s"; if (cardIndex < deletion.seq.length) { clozeAction = deletion.seq[cardIndex]; } switch (clozeAction) { case "a": frontText = frontText.replace(deletion.raw, formatter.asking(deletion.answer, deletion.hint)); break; case "h": frontText = frontText.replace(deletion.raw, formatter.hiding(deletion.answer, deletion.hint)); break; case "s": frontText = frontText.replace(deletion.raw, deletion.answer); break; } } return frontText; } getCardBack(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let backText = this.raw; for (const deletion of this._clozeDeletions) { let clozeAction = "s"; if (cardIndex < deletion.seq.length) { clozeAction = deletion.seq[cardIndex]; } switch (clozeAction) { case "a": backText = backText.replace(deletion.raw, formatter.showingAnswer(deletion.answer, deletion.hint)); break; case "h": backText = backText.replace(deletion.raw, formatter.hiding(deletion.answer, deletion.hint)); break; case "s": backText = backText.replace(deletion.raw, deletion.answer); break; } } return backText; } }; exports.ClozeNoteOL = ClozeNoteOL; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteSimple.js var require_ClozeNoteSimple = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeNoteSimple.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeNoteSimple = void 0; var ClozeNote_1 = require_ClozeNote(); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); var utils_1 = require_utils(); var ClozeNoteSimple = class extends ClozeNote_1.ClozeNote { constructor(raw, patterns) { super(raw, patterns); } get clozeType() { return ClozeTypeEnum_1.ClozeTypeEnum.SIMPLE; } initParsing(rawNote, patterns) { let clozeDeletions = []; let numCards = 0; patterns.forEach((pattern) => { const regex = pattern.getClozeRegex(ClozeTypeEnum_1.ClozeTypeEnum.SIMPLE); let match2; while (match2 = regex.exec(rawNote)) { numCards++; let newCloze = { raw: match2.raw, answer: match2.answer, seq: numCards, hint: match2.hint }; clozeDeletions.push(newCloze); } }); return { clozeDeletions, numCards }; } getCardFront(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let frontText = this.raw; for (const deletion of this._clozeDeletions) { if (deletion.seq !== cardIndex + 1) { frontText = frontText.replace(deletion.raw, deletion.answer); continue; } frontText = frontText.replace(deletion.raw, formatter.asking(deletion.answer, deletion.hint)); } return frontText; } getCardBack(cardIndex, formatter) { if (cardIndex >= this._numCards || cardIndex < 0) { throw new Error(`Card ${cardIndex} does not exist`); } if (!formatter) { formatter = new utils_1.simpleFormatter(); } let backText = this.raw; for (const deletion of this._clozeDeletions) { if (deletion.seq === cardIndex + 1) { backText = backText.replace(deletion.raw, formatter.showingAnswer(deletion.answer, deletion.hint)); } else { backText = backText.replace(deletion.raw, deletion.answer); } } return backText; } }; exports.ClozeNoteSimple = ClozeNoteSimple; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeTypeEnum.js var require_ClozeTypeEnum = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeTypeEnum.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NoteClassByClozeType = exports.ClozeTypesPriority = exports.ClozeTypeEnum = void 0; var ClozeNoteClassic_1 = require_ClozeNoteClassic(); var ClozeNoteOL_1 = require_ClozeNoteOL(); var ClozeNoteSimple_1 = require_ClozeNoteSimple(); var ClozeTypeEnum; (function(ClozeTypeEnum2) { ClozeTypeEnum2["CLASSIC"] = "classic"; ClozeTypeEnum2["OVERLAPPING"] = "overlapping"; ClozeTypeEnum2["SIMPLE"] = "simple"; })(ClozeTypeEnum || (exports.ClozeTypeEnum = ClozeTypeEnum = {})); exports.ClozeTypesPriority = [ ClozeTypeEnum.CLASSIC, ClozeTypeEnum.OVERLAPPING, ClozeTypeEnum.SIMPLE // Cloze Simple must be the last one because it is a subset of Cloze Classic and Cloze Overlapping ]; exports.NoteClassByClozeType = { [ClozeTypeEnum.CLASSIC]: ClozeNoteClassic_1.ClozeNoteClassic, [ClozeTypeEnum.OVERLAPPING]: ClozeNoteOL_1.ClozeNoteOL, [ClozeTypeEnum.SIMPLE]: ClozeNoteSimple_1.ClozeNoteSimple }; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozePattern.js var require_ClozePattern = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozePattern.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozePattern = void 0; var utils_1 = require_utils(); var ClozeRegExp_1 = require_ClozeRegExp(); var ClozeFieldEnum_1 = require_ClozeFieldEnum(); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); var numPatternRegex = new RegExp(`\\[(?:(?:\\\\\\])?[^\\]]?)+?\\d+(?:(?:\\\\\\])?[^\\]]?)+?\\]`); var hintPatternRegex = new RegExp(`\\[(?:(?:\\\\\\])?[^\\]]?)+?hint(?:(?:\\\\\\])?[^\\]]?)+?\\]`); var answerKeyword = `answer`; var ClozePattern = class _ClozePattern { constructor(raw) { this.clozeRegexByType = { [ClozeTypeEnum_1.ClozeTypeEnum.CLASSIC]: void 0, [ClozeTypeEnum_1.ClozeTypeEnum.OVERLAPPING]: void 0, [ClozeTypeEnum_1.ClozeTypeEnum.SIMPLE]: void 0 }; this.generateClozeRegexByType = { [ClozeTypeEnum_1.ClozeTypeEnum.CLASSIC]: this.generateClozeClassicRegex, [ClozeTypeEnum_1.ClozeTypeEnum.OVERLAPPING]: this.generateClozeOLRegex, [ClozeTypeEnum_1.ClozeTypeEnum.SIMPLE]: this.generateClozeSimpleRegex }; this._raw = raw; let _numMatch = numPatternRegex.exec(raw); let _hintMatch = hintPatternRegex.exec(raw); if (!_numMatch) { throw new Error("No cloze number pattern found"); } if (!_hintMatch) { throw new Error("No cloze hint pattern found"); } if (raw.indexOf(answerKeyword) == -1) { throw new Error(`No answer keyword (${answerKeyword}) found in the pattern.`); } this.numPattern = _numMatch; this.hintPattern = _hintMatch; this.numRegex = _ClozePattern.processPattern(_numMatch[0], (text) => text.replace(/\d+/g, "(\\d+)")); this.seqRegex = _ClozePattern.processPattern(_numMatch[0], (text) => text.replace(/\d+/g, "([ash]+)")); this.hintRegex = _ClozePattern.processPattern(_hintMatch[0], (text) => text.replace(/hint/g, "(.+?)")); this.hintRegex = "(?:" + this.hintRegex + ")?"; this._clozeFieldOrder = [ClozeFieldEnum_1.ClozeFieldEnum.answer, ClozeFieldEnum_1.ClozeFieldEnum.hint, ClozeFieldEnum_1.ClozeFieldEnum.seq]; let positions2 = { [ClozeFieldEnum_1.ClozeFieldEnum.answer]: raw.indexOf(answerKeyword), [ClozeFieldEnum_1.ClozeFieldEnum.hint]: this.hintPattern.index, [ClozeFieldEnum_1.ClozeFieldEnum.seq]: this.numPattern.index }; this._clozeFieldOrder.sort((a2, b2) => positions2[a2] - positions2[b2]); } static processPattern(text, rplc) { let ans = text.substring(1, text.length - 1); ans = ans.replace(/\\\[/g, "[").replace(/\\]/g, "]"); ans = (0, utils_1.escapeRegexString)(ans); ans = rplc(ans); return ans; } generateClozeRegexStr(first, firstReplace, second, secondReplace) { let begin = this._raw.slice(0, first.index); let middle = this._raw.slice(first.index + first[0].length, second.index); let ending = this._raw.slice(second.index + second[0].length, this._raw.length); let regexStr = (0, utils_1.escapeRegexString)(begin) + firstReplace + (0, utils_1.escapeRegexString)(middle) + secondReplace + (0, utils_1.escapeRegexString)(ending); regexStr = regexStr.replace(answerKeyword, "(.+?)"); return regexStr; } generateClozeSimpleRegex(pattern) { let regexStr; if (pattern.numPattern.index < pattern.hintPattern.index) { regexStr = pattern.generateClozeRegexStr(pattern.numPattern, "", pattern.hintPattern, pattern.hintRegex); } else { regexStr = pattern.generateClozeRegexStr(pattern.hintPattern, pattern.hintRegex, pattern.numPattern, ""); } let clozeFieldsOrderWithoutSeq = pattern._clozeFieldOrder.filter((x2) => x2 != ClozeFieldEnum_1.ClozeFieldEnum.seq); return new ClozeRegExp_1.ClozeRegExp(regexStr, clozeFieldsOrderWithoutSeq, "g"); } generateClozeClassicRegex(pattern) { let regexStr; if (pattern.numPattern.index < pattern.hintPattern.index) { regexStr = pattern.generateClozeRegexStr(pattern.numPattern, pattern.numRegex, pattern.hintPattern, pattern.hintRegex); } else { regexStr = pattern.generateClozeRegexStr(pattern.hintPattern, pattern.hintRegex, pattern.numPattern, pattern.numRegex); } return new ClozeRegExp_1.ClozeRegExp(regexStr, pattern._clozeFieldOrder, "g"); } generateClozeOLRegex(pattern) { let regexStr; if (pattern.numPattern.index < pattern.hintPattern.index) { regexStr = pattern.generateClozeRegexStr(pattern.numPattern, pattern.seqRegex, pattern.hintPattern, pattern.hintRegex); } else { regexStr = pattern.generateClozeRegexStr(pattern.hintPattern, pattern.hintRegex, pattern.numPattern, pattern.seqRegex); } return new ClozeRegExp_1.ClozeRegExp(regexStr, pattern._clozeFieldOrder, "g"); } get clozeFieldsOrder() { return this._clozeFieldOrder; } getClozeRegex(clozeType) { let clozeRegex = this.clozeRegexByType[clozeType]; if (clozeRegex != void 0) { clozeRegex.regex.lastIndex = 0; return clozeRegex; } clozeRegex = this.generateClozeRegexByType[clozeType](this); this.clozeRegexByType[clozeType] = clozeRegex; return clozeRegex; } hasClozeType(text, clozeType) { for (const priorityType of ClozeTypeEnum_1.ClozeTypesPriority) { if (this.getClozeRegex(priorityType).test(text)) { return clozeType == priorityType; } } return false; } getClozeTypes(text) { const clozeTypes = []; for (const priorityType of ClozeTypeEnum_1.ClozeTypesPriority) { if (this.getClozeRegex(priorityType).test(text)) { clozeTypes.push(priorityType); } } return clozeTypes; } getMainClozeType(text) { for (const priorityType of ClozeTypeEnum_1.ClozeTypesPriority) { if (this.getClozeRegex(priorityType).test(text)) { return priorityType; } } return null; } }; exports.ClozePattern = ClozePattern; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeCrafter.js var require_ClozeCrafter = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/implementation/ClozeCrafter.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeCrafter = void 0; var ClozePattern_1 = require_ClozePattern(); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); var ClozeCrafter3 = class { constructor(patterns) { this.patterns = patterns.map((patternStr) => new ClozePattern_1.ClozePattern(patternStr)); } createClozeNote(text) { const noteType = this.getNoteType(text); if (noteType === null) { return null; } const selectedClass = ClozeTypeEnum_1.NoteClassByClozeType[noteType]; const clozeNote = new selectedClass(text, this.patterns); return clozeNote; } getNoteType(text) { let noteType = null; for (const pattern of this.patterns) { const currentType = pattern.getMainClozeType(text); if (currentType !== null && (noteType === null || ClozeTypeEnum_1.ClozeTypesPriority.indexOf(currentType) < ClozeTypeEnum_1.ClozeTypesPriority.indexOf(noteType))) { noteType = currentType; } } return noteType; } isClozeNote(text) { return this.getNoteType(text) !== null; } }; exports.ClozeCrafter = ClozeCrafter3; } }); // node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/index.js var require_dist = __commonJS({ "node_modules/.pnpm/clozecraft@0.4.0/node_modules/clozecraft/dist/index.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClozeTypesPriority = exports.ClozeTypeEnum = exports.ClozeCrafter = void 0; var ClozeCrafter_1 = require_ClozeCrafter(); Object.defineProperty(exports, "ClozeCrafter", { enumerable: true, get: function() { return ClozeCrafter_1.ClozeCrafter; } }); var ClozeTypeEnum_1 = require_ClozeTypeEnum(); Object.defineProperty(exports, "ClozeTypeEnum", { enumerable: true, get: function() { return ClozeTypeEnum_1.ClozeTypeEnum; } }); Object.defineProperty(exports, "ClozeTypesPriority", { enumerable: true, get: function() { return ClozeTypeEnum_1.ClozeTypesPriority; } }); } }); // node_modules/.pnpm/vhtml@2.2.0/node_modules/vhtml/dist/vhtml.js var require_vhtml = __commonJS({ "node_modules/.pnpm/vhtml@2.2.0/node_modules/vhtml/dist/vhtml.js"(exports, module2) { (function(global, factory) { typeof exports === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.vhtml = factory(); })(exports, function() { "use strict"; var emptyTags = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]; var esc = function esc2(str) { return String(str).replace(/[&<>"']/g, function(s2) { return "&" + map3[s2] + ";"; }); }; var map3 = { "&": "amp", "<": "lt", ">": "gt", '"': "quot", "'": "apos" }; var setInnerHTMLAttr = "dangerouslySetInnerHTML"; var DOMAttributeNames = { className: "class", htmlFor: "for" }; var sanitized = {}; function h6(name, attrs) { var stack = [], s2 = ""; attrs = attrs || {}; for (var i2 = arguments.length; i2-- > 2; ) { stack.push(arguments[i2]); } if (typeof name === "function") { attrs.children = stack.reverse(); return name(attrs); } if (name) { s2 += "<" + name; if (attrs) for (var _i in attrs) { if (attrs[_i] !== false && attrs[_i] != null && _i !== setInnerHTMLAttr) { s2 += " " + (DOMAttributeNames[_i] ? DOMAttributeNames[_i] : esc(_i)) + '="' + esc(attrs[_i]) + '"'; } } s2 += ">"; } if (emptyTags.indexOf(name) === -1) { if (attrs[setInnerHTMLAttr]) { s2 += attrs[setInnerHTMLAttr].__html; } else while (stack.length) { var child = stack.pop(); if (child) { if (child.pop) { for (var _i2 = child.length; _i2--; ) { stack.push(child[_i2]); } } else { s2 += sanitized[child] === true ? child : esc(child); } } } s2 += name ? "" + name + ">" : ""; } sanitized[s2] = true; return s2; } return h6; }); } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => SRPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian14 = require("obsidian"); // src/algorithms/base/repetition-item.ts var RepetitionItem = class { // scheduling get hasSchedule() { return this.scheduleInfo != null; } get isNew() { return !this.hasSchedule; } get isDue() { return this.hasSchedule && this.scheduleInfo.isDue(); } }; // src/algorithms/base/srs-algorithm.ts var SrsAlgorithm = class _SrsAlgorithm { static getInstance() { if (!_SrsAlgorithm.instance) { throw new Error("there is no SrsAlgorithm instance."); } return _SrsAlgorithm.instance; } }; // src/algorithms/osr/obsidian-vault-notelink-info-finder.ts var ObsidianVaultNoteLinkInfoFinder = class { constructor(metadataCache) { this.metadataCache = metadataCache; } getResolvedTargetLinksForNotePath(path3) { return this.metadataCache.resolvedLinks[path3]; } }; // src/algorithms/osr/srs-algorithm-osr.ts var import_moment2 = __toESM(require_moment()); // src/constants.ts var SCHEDULING_INFO_REGEX = /^---\r?\n((?:.*\r?\n)*)sr-due: (.+)\r?\nsr-interval: (\d+)\r?\nsr-ease: (\d+)\r?\n((?:.*\r?\n)?)---/; var YAML_FRONT_MATTER_REGEX = /^---\r?\n((?:.*\r?\n)*?)---/; var MULTI_SCHEDULING_EXTRACTOR = /!([\d-]+),(\d+),(\d+)/gm; var LEGACY_SCHEDULING_EXTRACTOR = //gm; var OBSIDIAN_TAG_AT_STARTOFLINE_REGEX = /^#[^\s#]+/gi; var OBSIDIAN_BLOCK_ID_ENDOFLINE_REGEX = / (\^[a-zA-Z0-9-]+)$/; var PREFERRED_DATE_FORMAT = "YYYY-MM-DD"; var ALLOWED_DATE_FORMATS = [PREFERRED_DATE_FORMAT, "DD-MM-YYYY", "ddd MMM DD YYYY"]; var IMAGE_FORMATS = [ "jpg", "jpeg", "gif", "png", "svg", "webp", "apng", "avif", "jfif", "pjpeg", "pjp", "bmp" ]; var AUDIO_FORMATS = ["mp3", "webm", "m4a", "wav", "ogg"]; var VIDEO_FORMATS = ["mp4", "mkv", "avi", "mov"]; var COLLAPSE_ICON = ''; var TICKS_PER_DAY = 24 * 3600 * 1e3; var SR_HTML_COMMENT_BEGIN = ""; // src/lang/helpers.ts var import_obsidian = require("obsidian"); // src/lang/locale/af.ts var af_default = {}; // src/lang/locale/ar.ts var ar_default = { // flashcard-modal.tsx DECKS: "\u0627\u0644\u0631\u064F\u0632\u0645\u064E\u0627\u062A", DUE_CARDS: "\u0628\u0637\u0627\u0642\u0627\u062A \u0645\u064F\u0633\u062A\u062D\u0642\u0629", NEW_CARDS: "\u0628\u0637\u0627\u0642\u0627\u062A \u062C\u062F\u064A\u062F\u0629", TOTAL_CARDS: "\u0625\u062C\u0645\u0627\u0644\u064A \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", BACK: "\u0631\u062C\u0648\u0639", SKIP: "Skip", EDIT_CARD: "\u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0629", RESET_CARD_PROGRESS: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u062A\u0642\u062F\u0651\u064F\u0645\u0652 \u0627\u0644\u0628\u0637\u0627\u0642\u0629", HARD: "\u0635\u0639\u0628", GOOD: "\u062C\u064A\u062F", EASY: "\u0633\u0647\u0644", SHOW_ANSWER: "\u0623\u0638\u0647\u0650\u0631 \u0627\u0644\u0625\u062C\u0627\u0628\u0629", CARD_PROGRESS_RESET: ".\u062A\u0645\u0651\u064E\u062A \u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u062A\u0642\u062F\u0651\u064F\u0645 \u0627\u0644\u0628\u0637\u0627\u0642\u0629", SAVE: "\u062D\u0641\u0638", CANCEL: "\u0625\u0644\u063A\u0627\u0621", NO_INPUT: ".\u0644\u0645 \u064A\u062A\u0650\u0645 \u062A\u0642\u062F\u064A\u0645 \u0623\u064A \u0645\u064F\u062F\u062E\u0644\u0627\u062A", CURRENT_EASE_HELP_TEXT: ":\u0627\u0644\u0633\u0647\u0648\u0644\u0629 \u0627\u0644\u062D\u0627\u0644\u064A\u0629", CURRENT_INTERVAL_HELP_TEXT: ":\u0627\u0644\u0641\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A \u0627\u0644\u062D\u0627\u0644\u064A", CARD_GENERATED_FROM: "${notePath} :\u062A\u0645 \u0625\u0646\u0634\u0627\u0624\u0647\u0627 \u0645\u0646", // main.ts OPEN_NOTE_FOR_REVIEW: "\u0627\u0641\u062A\u062D \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629 \u0644\u0644\u0645\u0631\u0627\u062C\u0639\u0629", REVIEW_CARDS: "\u0645\u0631\u0627\u062C\u0639\u0629 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", REVIEW_DIFFICULTY_FILE_MENU: "${difficulty} :\u0645\u0631\u0627\u062C\u0639\u0629", REVIEW_NOTE_DIFFICULTY_CMD: "${difficulty} \u0645\u0631\u0627\u062C\u0639\u0629 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629 \u0643\u0640", CRAM_ALL_CARDS: "\u062D\u062F\u062F \u0631\u064F\u0632\u0645\u064E\u0629 \u0644\u0644\u062D\u0634\u0631", REVIEW_ALL_CARDS: "\u0645\u0631\u0627\u062C\u0639\u0629 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0645\u0646 \u062C\u0645\u064A\u0639 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0627\u062A", REVIEW_CARDS_IN_NOTE: "\u0645\u0631\u0627\u062C\u0639\u0629 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0645\u0646 \u0647\u0630\u0647 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629", CRAM_CARDS_IN_NOTE: "\u0623\u062D\u0634\u0631 \u062C\u0645\u064A\u0639 \u0628\u0637\u0627\u0642\u0627\u062A \u0647\u0630\u0647 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629", VIEW_STATS: "\u0639\u0631\u0636 \u0627\u0644\u0625\u062D\u0635\u0627\u0626\u064A\u0627\u062A", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "\u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0645\u0633\u062A\u062D\u0642\u0629 ${dueFlashcardsCount},\u0645\u0644\u0627\u062D\u0638\u0627\u062A ${dueNotesCount}:\u0645\u0631\u0627\u062C\u0639\u0629", SYNC_TIME_TAKEN: "${t}ms \u0627\u0633\u062A\u063A\u0631\u0627\u0642 \u0627\u0644\u0645\u0632\u0627\u0645\u0646\u0629", NOTE_IN_IGNORED_FOLDER: ".\u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629 \u064A\u062A\u0645 \u062D\u0641\u0638\u0647\u0627 \u0636\u0645\u0646 \u0627\u0644\u0645\u062C\u0644\u062F \u0627\u0644\u0630\u064A \u062A\u0645 \u062A\u062C\u0627\u0647\u0644\u0647 (\u062A\u062D\u0642\u0642 \u0645\u0646 \u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A)", PLEASE_TAG_NOTE: ".\u064A\u0631\u062C\u0649 \u0648\u0636\u0639 \u0648\u0633\u0645 \u0639\u0644\u0649 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629 \u0628\u0634\u0643\u0644 \u0645\u0646\u0627\u0633\u0628 \u0644\u0644\u0645\u0631\u0627\u062C\u0639\u0629 (\u0641\u064A \u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A)", RESPONSE_RECEIVED: ".\u0627\u0633\u062A\u064F\u0644\u0645\u062A \u0627\u0644\u0627\u0633\u062A\u062C\u0627\u0628\u0629", NO_DECK_EXISTS: "${deckName} \u0644\u0627 \u064A\u0648\u062C\u062F \u0631\u064F\u0632\u0645\u064E\u0629", ALL_CAUGHT_UP: "\u{1F606} \u0644\u0642\u062F \u062A\u0645 \u0627\u0644\u0642\u0628\u0636 \u0639\u0644\u064A\u0643\u0645 \u062C\u0645\u064A\u0639\u0627 \u0627\u0644\u0622\u0646", // scheduling.ts DAYS_STR_IVL: "\u064A\u0648\u0645/\u0623\u064A\u0627\u0645 ${interval}", MONTHS_STR_IVL: "\u0634\u0647\u0631/\u0623\u0634\u0647\u0631 ${interval}", YEARS_STR_IVL: "\u0633\u0646\u0629/\u0633\u0646\u0648\u0627\u062A ${interval}", DAYS_STR_IVL_MOBILE: "\u064A${interval}", MONTHS_STR_IVL_MOBILE: "\u0634${interval}", YEARS_STR_IVL_MOBILE: "\u0633${interval}", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '.wiki \u0644\u0645\u0632\u064A\u062F \u0645\u0646 \u0627\u0644\u0645\u0639\u0644\u0648\u0645\u0627\u062A \u060C \u062A\u062D\u0642\u0642 \u0645\u0646', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\u0645\u062C\u0644\u062F\u0627\u062A \u0644\u062A\u062C\u0627\u0647\u0644\u0647\u0627", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", FLASHCARD_EASY_LABEL: "\u0646\u0635 \u0627\u0644\u0632\u0631 \u0633\u0647\u0644", FLASHCARD_GOOD_LABEL: "\u0646\u0635 \u0627\u0644\u0632\u0631 \u062C\u064A\u062F", FLASHCARD_HARD_LABEL: "\u0646\u0635 \u0627\u0644\u0632\u0631 \u0635\u0639\u0628", FLASHCARD_EASY_DESC: '"\u062A\u062E\u0635\u064A\u0635 \u0627\u0644\u062A\u0633\u0645\u064A\u0629 \u0644\u0644\u0632\u0631 "\u0633\u0647\u0644', FLASHCARD_GOOD_DESC: '"\u062A\u062E\u0635\u064A\u0635 \u0627\u0644\u062A\u0633\u0645\u064A\u0629 \u0644\u0644\u0632\u0631 "\u062C\u064A\u062F', FLASHCARD_HARD_DESC: '"\u062A\u062E\u0635\u064A\u0635 \u0627\u0644\u062A\u0633\u0645\u064A\u0629 \u0644\u0644\u0632\u0631 "\u0635\u0639\u0628', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\u0648\u064F\u0633\u0648\u0645 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", FLASHCARD_TAGS_DESC: "#2\u0623\u062F\u062E\u0644 \u0627\u0644\u0648\u064F\u0633\u0648\u0645 \u0645\u0641\u0635\u0648\u0644\u0629 \u0628\u0645\u0633\u0627\u0641\u0627\u062A \u0623\u0648 \u0623\u0633\u0637\u0631 \u062C\u062F\u064A\u062F\u0629 \u060C \u0623\u064A \u0628\u0637\u0627\u0642\u0627\u062A# \u0631\u0632\u0645\u06293# \u0631\u0632\u0645\u0629", CONVERT_FOLDERS_TO_DECKS: "\u062A\u062D\u0648\u064A\u0644 \u0627\u0644\u0645\u062C\u0644\u062F\u0627\u062A \u0625\u0644\u0649 \u0645\u0644\u0641\u0627\u062A \u0623\u0635\u0644\u064A\u0629 \u0648 \u0645\u0644\u0641\u0627\u062A \u0627\u0644\u0641\u0631\u0639\u064A\u0629\u061F", CONVERT_FOLDERS_TO_DECKS_DESC: ".\u0647\u0630\u0627 \u0647\u0648 \u0628\u062F\u064A\u0644 \u0644\u062E\u064A\u0627\u0631 \u0648\u0633\u0648\u0645 \u0627\u0644\u0628\u0637\u0627\u0642\u0629 \u0623\u0639\u0644\u0627\u0647", INLINE_SCHEDULING_COMMENTS: "\u062D\u0641\u0638 \u062A\u0639\u0644\u064A\u0642 \u0627\u0644\u062C\u062F\u0648\u0644\u0629 \u0639\u0644\u0649 \u0646\u0641\u0633 \u0627\u0644\u0633\u0637\u0631 \u0645\u062B\u0644 \u0627\u0644\u0633\u0637\u0631 \u0627\u0644\u0623\u062E\u064A\u0631 \u0644\u0644\u0628\u0637\u0627\u0642\u0629 \u061F", INLINE_SCHEDULING_COMMENTS_DESC: "\u0644\u0627 \u062A\u0643\u0633\u0631 \u062A\u0646\u0633\u064A\u0642 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 HTML \u0633\u064A\u0624\u062F\u064A \u062A\u0634\u063A\u064A\u0644 \u0647\u0630\u0627 \u0625\u0644\u0649 \u062C\u0639\u0644 \u062A\u0639\u0644\u064A\u0642\u0627\u062A", BURY_SIBLINGS_TILL_NEXT_DAY: "\u0623\u062E\u0641\u064A \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0634\u0642\u064A\u0642\u0629 \u062D\u062A\u0649 \u0627\u0644\u064A\u0648\u0645 \u0627\u0644\u062A\u0627\u0644\u064A", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "cloze deletions : \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0634\u0642\u064A\u0642\u0629 \u0647\u064A \u0628\u0637\u0627\u0642\u0627\u062A \u062A\u0645 \u0625\u0646\u0634\u0627\u0624\u0647\u0627 \u0645\u0646 \u0646\u0641\u0633 \u0646\u0635 \u0627\u0644\u0628\u0637\u0627\u0642\u0629 \u0643\u0640", SHOW_CARD_CONTEXT: "\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0633\u064A\u0627\u0642 \u0641\u064A \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A\u061F", SHOW_CARD_CONTEXT_DESC: "i.e. Title > Heading 1 > Subheading > ... > Subheading", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\u0646\u0633\u0628\u0629 \u0627\u0631\u062A\u0641\u0627\u0639 \u0627\u0644\u0628\u0637\u0627\u0642\u0629", CARD_MODAL_SIZE_PERCENT_DESC: "\u064A\u062C\u0628 \u0636\u0628\u0637\u0647\u0627 \u0639\u0644\u0649 100 \u066A \u0639\u0644\u0649 \u0627\u0644\u0647\u0627\u062A\u0641 \u0627\u0644\u0645\u062D\u0645\u0648\u0644 \u0623\u0648 \u0625\u0630\u0627 \u0643\u0627\u0646 \u0644\u062F\u064A\u0643 \u0635\u0648\u0631 \u0643\u0628\u064A\u0631\u0629 \u062C\u062F\u064B\u0627", RESET_DEFAULT: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u0625\u0644\u0649 \u0627\u0644\u0627\u0641\u062A\u0631\u0627\u0636\u064A", CARD_MODAL_WIDTH_PERCENT: "\u0646\u0633\u0628\u0629 \u0639\u0631\u0636 \u0627\u0644\u0628\u0637\u0627\u0642\u0629", RANDOMIZE_CARD_ORDER: "\u062A\u0631\u062A\u064A\u0628 \u0628\u0637\u0627\u0642\u0629 \u0639\u0634\u0648\u0627\u0626\u064A \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0629\u061F", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "\u061Fcloze \u062A\u0639\u0637\u064A\u0644 \u0628\u0637\u0627\u0642\u0627\u062A", CONVERT_HIGHLIGHTS_TO_CLOZES: "Convert ==highlights== to clozes", CONVERT_BOLD_TEXT_TO_CLOZES: "Convert **bolded text** to clozes", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convert {{curly brackets}} to clozes", CLOZE_PATTERNS: "Cloze Patterns", CLOZE_PATTERNS_DESC: 'Enter cloze patterns separated by newlines. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\u0641\u0627\u0635\u0644 \u0645\u0646 \u0623\u062C\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0645\u0636\u0645\u0646\u0629", FIX_SEPARATORS_MANUALLY_WARNING: "\u0636\u0639 \u0641\u064A \u062D\u0633\u0627\u0628\u0643 \u0623\u0646\u0647 \u0628\u0639\u062F \u062A\u063A\u064A\u064A\u0631 \u0647\u0630\u0627 \u060C \u064A\u062C\u0628 \u0639\u0644\u064A\u0643 \u062A\u0639\u062F\u064A\u0644 \u0623\u064A \u0628\u0637\u0627\u0642\u0627\u062A \u0644\u062F\u064A\u0643 \u0628\u0627\u0644\u0641\u0639\u0644 \u064A\u062F\u0648\u064A\u064B\u0627", INLINE_REVERSED_CARDS_SEPARATOR: "\u0641\u0627\u0635\u0644 \u0645\u0646 \u0623\u062C\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0639\u0643\u0633\u064A\u0629 \u0627\u0644\u0645\u0636\u0645\u0646\u0629", MULTILINE_CARDS_SEPARATOR: "\u0641\u0627\u0635\u0644 \u0645\u0646 \u0623\u062C\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0645\u062A\u0639\u062F\u062F\u0629", MULTILINE_REVERSED_CARDS_SEPARATOR: "\u0641\u0627\u0635\u0644 \u0645\u0646 \u0623\u062C\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0639\u0643\u0633\u064A\u0629 \u0627\u0644\u0645\u062A\u0639\u062F\u062F\u0629", MULTILINE_CARDS_END_MARKER: "\u0627\u0644\u0623\u062D\u0631\u0641 \u0627\u0644\u062A\u064A \u062A\u062F\u0644 \u0639\u0644\u0649 \u0646\u0647\u0627\u064A\u0629 \u0627\u0644\u0643\u0644\u0648\u0632\u0627\u062A \u0648\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u062A\u0639\u0644\u0645 \u0627\u0644\u0645\u062A\u0639\u062F\u062F\u0629 \u0627\u0644\u0623\u0633\u0637\u0631", NOTES: "\u0645\u0644\u0627\u062D\u0638\u0627\u062A", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "\u062A\u0645\u0643\u064A\u0646 \u062C\u0632\u0621 \u0645\u0631\u0627\u062C\u0639\u0629 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0627\u062A \u0639\u0646\u062F \u0628\u062F\u0621 \u0627\u0644\u062A\u0634\u063A\u064A\u0644", TAGS_TO_REVIEW: "\u0648\u0633\u0648\u0645 \u0644\u0644\u0645\u0631\u0627\u062C\u0639\u0629", TAGS_TO_REVIEW_DESC: "#\u0623\u062F\u062E\u0644 \u0627\u0644\u0648\u0633\u0648\u0645 \u0645\u0641\u0635\u0648\u0644\u0629 \u0628\u0645\u0633\u0627\u0641\u0627\u062A \u0623\u0648 \u062E\u0637\u0648\u0637 \u062C\u062F\u064A\u062F\u0629 \u060C \u0623\u064A : \u0645\u0631\u0627\u062C\u0639\u0629# \u0648\u0633\u06452# \u0648\u0633\u06453", OPEN_RANDOM_NOTE: "\u0627\u0641\u062A\u062D \u0645\u0644\u0627\u062D\u0638\u0629 \u0639\u0634\u0648\u0627\u0626\u064A\u0629 \u0644\u0644\u0645\u0631\u0627\u062C\u0639\u0629", OPEN_RANDOM_NOTE_DESC: "(Pagerank) \u0639\u0646\u062F \u062A\u0639\u0637\u064A\u0644 \u0647\u0630\u0627 \u0627\u0644\u062E\u064A\u0627\u0631 \u060C\u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0627\u062A \u0633\u064A\u062A\u0645 \u062A\u0631\u062A\u064A\u0628\u064F\u0647\u0627 \u062D\u0633\u0628 \u0627\u0644\u0623\u0647\u0645\u064A\u0629", AUTO_NEXT_NOTE: "\u0627\u0641\u062A\u062D \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629 \u062A\u0644\u0642\u0627\u0626\u064A\u064B\u0627 \u0628\u0639\u062F \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0629", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\u0641\u0639\u0651\u0644 \u062E\u064A\u0627\u0631\u0627\u062A \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0629 \u0641\u064A \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0644\u0641 (\u0645\u062B\u0627\u0644: \u0645\u0631\u0627\u062C\u0639\u0629: \u0633\u0647\u0644\u060C \u062C\u064A\u062F\u060C \u0635\u0639\u0628)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\u0625\u0630\u0627 \u0642\u0645\u062A \u0628\u062A\u0639\u0637\u064A\u0644 \u062E\u064A\u0627\u0631\u0627\u062A \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0629 \u0641\u064A \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0644\u0641\u060C \u064A\u0645\u0643\u0646\u0643 \u0645\u0631\u0627\u062C\u0639\u0629 \u0645\u0644\u0627\u062D\u0638\u0627\u062A\u0643 \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u0625\u0636\u0627\u0641\u0629 \u0648\u0625\u0630\u0627 \u0643\u0646\u062A \u0642\u062F \u062D\u062F\u062F\u062A\u0647\u0627\u060C \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0645\u0641\u0627\u062A\u064A\u062D \u0627\u0644\u0627\u062E\u062A\u0635\u0627\u0631 \u0627\u0644\u0645\u0631\u062A\u0628\u0637\u0629.", MAX_N_DAYS_REVIEW_QUEUE: "\u0627\u0644\u062D\u062F \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0639\u062F\u062F \u0627\u0644\u0623\u064A\u0627\u0645 \u0627\u0644\u062A\u064A \u064A\u062C\u0628 \u0639\u0631\u0636\u0647\u0627 \u0639\u0644\u0649 \u0627\u0644\u0644\u0648\u062D\u0629 \u0627\u0644\u064A\u0645\u0646\u0649", MIN_ONE_DAY: "\u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0639\u062F\u062F \u0627\u0644\u0623\u064A\u0627\u0645 1 \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644", VALID_NUMBER_WARNING: "\u064A\u0631\u062C\u0649 \u062A\u0642\u062F\u064A\u0645 \u0631\u0642\u0645 \u0635\u0627\u0644\u062D", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0627\u0644\u0639\u0631\u0636 \u0627\u0644\u0634\u062C\u0631\u064A \u0644\u0644\u0631\u064F\u0632\u0645 \u0645\u0648\u0633\u0639 \u0628\u062D\u064A\u062B \u062A\u0637\u0647\u0631 \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u0641\u0631\u0639\u064A\u0629 \u0643\u0644\u0647\u0627", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: " \u0639\u0637\u0644 \u0647\u0630\u0627 \u0627\u0644\u062E\u064A\u0627\u0631 \u0644\u0637\u064A \u0627\u0644\u0631\u064F\u0632\u0645 \u0627\u0644\u0645\u062A\u062F\u0627\u062E\u0644\u0629 \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0628\u0637\u0627\u0642\u0629 , \u0645\u0641\u064A\u062F \u0625\u0630\u0627 \u0643\u0627\u0646 \u0644\u062F\u064A\u0643 \u0628\u0637\u0627\u0642\u0627\u062A \u062A\u0646\u062A\u0645\u064A \u0625\u0644\u0649 \u0627\u0644\u0639\u062F\u064A\u062F \u0645\u0646 \u0627\u0644\u0631\u064F\u0632\u0645 \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0645\u0644\u0641", ALGORITHM: "\u062E\u0648\u0627\u0631\u0632\u0645\u064A\u0629", CHECK_ALGORITHM_WIKI: 'algorithm details :\u0644\u0645\u0632\u064A\u062F \u0645\u0646 \u0627\u0644\u0645\u0639\u0644\u0648\u0645\u0627\u062A \u062A\u062D\u0642\u0642 \u0645\u0646', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\u0633\u0647\u0648\u0644\u0629 \u0627\u0644\u0642\u0627\u0639\u062F\u0629", BASE_EASE_DESC: "\u0627\u0644\u062D\u062F \u0627\u0644\u0623\u062F\u0646\u0649 = 130 \u060C \u0648\u064A\u0641\u0636\u0644 \u062D\u0648\u0627\u0644\u064A 250.", BASE_EASE_MIN_WARNING: "\u064A\u062C\u0628 \u0623\u0646 \u062A\u0643\u0648\u0646 \u0633\u0647\u0648\u0644\u0629 \u0627\u0644\u0642\u0627\u0639\u062F\u0629 130 \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644.", LAPSE_INTERVAL_CHANGE: "\u0627\u0644\u0641\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A \u064A\u062A\u063A\u064A\u0631 \u0639\u0646\u062F \u0645\u0631\u0627\u062C\u0639\u0629 \u0628\u0637\u0627\u0642\u0629/\u0645\u0644\u0627\u062D\u0638\u0629 \u0635\u0639\u0628\u0629", LAPSE_INTERVAL_CHANGE_DESC: "newInterval = oldInterval * intervalChange / 100.", EASY_BONUS: "\u0645\u0643\u0627\u0641\u0623\u0629 \u0633\u0647\u0644\u0629", EASY_BONUS_DESC: "\u062A\u062A\u064A\u062D \u0644\u0643 \u0627\u0644\u0645\u0643\u0627\u0641\u0623\u0629 \u0627\u0644\u0633\u0647\u0644\u0629 \u0636\u0628\u0637 \u0627\u0644\u0641\u0631\u0642 \u0641\u064A \u0627\u0644\u0641\u0648\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A\u0629 \u0628\u064A\u0646 \u0627\u0644\u0631\u062F \u0627\u0644\u062C\u064A\u062F \u0648\u0627\u0644\u0633\u0647\u0644 \u0639\u0644\u0649 \u0628\u0637\u0627\u0642\u0629/\u0645\u0644\u0627\u062D\u0638\u0629 (\u0627\u0644\u062D\u062F \u0627\u0644\u0623\u062F\u0646\u0649 = 100 \u066A).", EASY_BONUS_MIN_WARNING: "\u064A\u062C\u0628 \u0623\u0646 \u062A\u0643\u0648\u0646 \u0627\u0644\u0645\u0643\u0627\u0641\u0623\u0629 \u0627\u0644\u0633\u0647\u0644\u0629 100 \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximum interval in days", MAX_INTERVAL_DESC: "\u064A\u062A\u064A\u062D \u0644\u0643 \u0648\u0636\u0639 \u062D\u062F \u0623\u0639\u0644\u0649 \u0644\u0644\u0641\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A (\u0627\u0641\u062A\u0631\u0627\u0636\u064A = 100 \u0639\u0627\u0645).", MAX_INTERVAL_MIN_WARNING: "\u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0627\u0644\u062D\u062F \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0644\u0641\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A \u0644\u0645\u062F\u0629 \u064A\u0648\u0645 \u0648\u0627\u062D\u062F \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644.", MAX_LINK_CONTRIB: "\u0623\u0642\u0635\u0649 \u0645\u0633\u0627\u0647\u0645\u0629 \u0627\u0631\u062A\u0628\u0627\u0637", MAX_LINK_CONTRIB_DESC: "\u0623\u0642\u0635\u0649 \u0645\u0633\u0627\u0647\u0645\u0629 \u0644\u0644\u0633\u0647\u0648\u0644\u0629 \u0627\u0644\u0645\u0631\u062C\u062D\u0629 \u0644\u0644\u0645\u0644\u0627\u062D\u0638\u0627\u062A \u0627\u0644\u0645\u0631\u062A\u0628\u0637\u0629 \u0628\u0627\u0644\u0633\u0647\u0648\u0644\u0629 \u0627\u0644\u0623\u0648\u0644\u064A\u0629.", LOGGING: "\u062A\u0633\u062C\u064A\u0644", DISPLAY_SCHEDULING_DEBUG_INFO: "\u0639\u0631\u0636 \u0645\u0639\u0644\u0648\u0645\u0627\u062A \u0627\u0644\u062A\u0635\u062D\u064A\u062D \u0639\u0644\u0649 \u0648\u062D\u062F\u0629 \u062A\u062D\u0643\u0645 \u0627\u0644\u0645\u0637\u0648\u0631", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\u0645\u0644\u0627\u062D\u0638\u0627\u062A \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0629", CLOSE: "\u0623\u063A\u0644\u0642", NEW: "\u062C\u062F\u064A\u062F", YESTERDAY: "\u0627\u0644\u0628\u0627\u0631\u062D\u0629", TODAY: "\u0627\u0644\u064A\u0648\u0645", TOMORROW: "\u0627\u0644\u063A\u062F", // stats-modal.tsx STATS_TITLE: "\u0625\u062D\u0635\u0627\u0626\u064A\u0627\u062A", MONTH: "\u0634\u0647\u0631", QUARTER: "\u0631\u0628\u0639 \u0627\u0644\u0633\u0646\u0629", YEAR: "\u0633\u0646\u0629", LIFETIME: "", FORECAST: "", FORECAST_DESC: "\u0639\u062F\u062F \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0645\u0633\u062A\u062D\u0642\u0629 \u0641\u064A \u0627\u0644\u0645\u0633\u062A\u0642\u0628\u0644", SCHEDULED: "\u0627\u0644\u0645\u0642\u0631\u0631", DAYS: "\u0623\u064A\u0627\u0645", NUMBER_OF_CARDS: "\u0639\u062F\u062F \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", REVIEWS_PER_DAY: "\u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0627\u062A/\u0627\u0644\u064A\u0648\u0645 ${avg} :\u0645\u062A\u0648\u0633\u0637", INTERVALS: "\u0641\u0648\u0627\u0635\u0644 \u0632\u0645\u0646\u064A\u0629", INTERVALS_DESC: "\u0627\u0644\u062A\u0623\u062E\u064A\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u0639\u0631\u0636 \u0627\u0644\u0645\u0631\u0627\u062C\u0639\u0627\u062A \u0645\u0631\u0629 \u0623\u062E\u0631\u0649", COUNT: "\u0639\u062F\u062F", INTERVALS_SUMMARY: "${longest} : \u0623\u0637\u0648\u0644 \u0641\u0627\u0635\u0644 \u0632\u0645\u0646\u064A ,${avg} :\u0645\u062A\u0648\u0633\u0637 \u0627\u0644\u0641\u0627\u0635\u0644 \u0627\u0644\u0632\u0645\u0646\u064A", EASES: "\u0627\u0644\u0633\u0647\u0648\u0644\u0629", EASES_SUMMARY: "${avgEase} :\u0645\u062A\u0648\u0633\u0637 \u0627\u0644\u0633\u0647\u0648\u0644\u0629", EASE: "Ease", CARD_TYPES: "\u0623\u0646\u0648\u0627\u0639 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", CARD_TYPES_DESC: "\u0648\u0647\u0630\u0627 \u064A\u0634\u0645\u0644 \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A \u0627\u0644\u0645\u062E\u0641\u064A\u0629 \u0643\u0630\u0644\u0643 \u060C \u0625\u0646 \u0648\u062C\u062F\u062A", CARD_TYPE_NEW: "\u062C\u062F\u064A\u062F\u0629", CARD_TYPE_YOUNG: "\u0635\u063A\u064A\u0631\u0629", CARD_TYPE_MATURE: "\u0646\u0627\u0636\u062C\u0629", CARD_TYPES_SUMMARY: " ${totalCardsCount} :\u0625\u062C\u0645\u0627\u0644\u064A \u0639\u062F\u062F \u0627\u0644\u0628\u0637\u0627\u0642\u0627\u062A", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/bn.ts var bn_default = {}; // src/lang/locale/cz.ts var cz_default = { // flashcard-modal.tsx DECKS: "Bal\xED\u010Dky", DUE_CARDS: "Karti\u010Dky po term\xEDnu", NEW_CARDS: "Nov\xE9 karti\u010Dky", TOTAL_CARDS: "Karti\u010Dek celkem", BACK: "Back", SKIP: "Skip", EDIT_CARD: "Edit Card", RESET_CARD_PROGRESS: "Vynulovat pokrok karti\u010Dky", HARD: "T\u011B\u017Ek\xE9", GOOD: "Dobr\xE9", EASY: "Jednoduch\xE9", SHOW_ANSWER: "Uk\xE1zat odpov\u011B\u010F", CARD_PROGRESS_RESET: "Pokrok karti\u010Dky byl vynulov\xE1n.", SAVE: "Save", CANCEL: "Cancel", NO_INPUT: "No input provided.", CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Otev\u0159\xEDt pozn\xE1mku k revizi", REVIEW_CARDS: "Pozn\xE1mek k revizi", REVIEW_DIFFICULTY_FILE_MENU: "Revize: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Ozna\u010Dit pozn\xE1mku jako ${difficulty}", REVIEW_ALL_CARDS: "Revidovat karti\u010Dky ve v\u0161ech pozn\xE1mk\xE1ch", CRAM_ALL_CARDS: "Select a deck to cram", REVIEW_CARDS_IN_NOTE: "Revidovat karti\u010Dky v t\xE9to pozn\xE1mce.", CRAM_CARDS_IN_NOTE: "Cram karti\u010Dky v t\xE9to pozn\xE1mce.", VIEW_STATS: "Uk\xE1zat statistiky", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Revize: ${dueNotesCount} pozn\xE1mek, ${dueFlashcardsCount} karti\u010Dek po term\xEDnu", SYNC_TIME_TAKEN: "Synchronizace trvala ${t}ms", NOTE_IN_IGNORED_FOLDER: "Pozn\xE1mka je ulo\u017Eena v ignorovan\xE9 slo\u017Ece (zkontrolujte nastaven\xED).", PLEASE_TAG_NOTE: "Pros\xEDm ozna\u010Dne pozn\xE1mku odpov\xEDdaj\xEDc\xEDm tagem pro revizi (v nastaven\xED).", RESPONSE_RECEIVED: "Odpov\u011B\u010F p\u0159ijata.", NO_DECK_EXISTS: "Neexistuje \u017E\xE1dn\xFD bal\xED\u010Dek pro ${deckName}", ALL_CAUGHT_UP: "V\u0161e zrevidov\xE1no", // scheduling.ts DAYS_STR_IVL: "${interval} den/dn\xED", MONTHS_STR_IVL: "${interval} m\u011Bs\xEDc(\u016F)", YEARS_STR_IVL: "${interval} rok(\u016F)", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}r", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Pro v\xEDce informac\xED jd\u011Bte na wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Ignorovan\xE9 slo\u017Eky", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Karti\u010Dky", FLASHCARD_EASY_LABEL: "Easy Button Text", FLASHCARD_GOOD_LABEL: "Good Button Text", FLASHCARD_HARD_LABEL: "Hard Button Text", FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button', FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button', FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Tag pro karti\u010Dky", FLASHCARD_TAGS_DESC: "Zadete tagy ood\u011Blen\xE9 mezerou nebo od\u0159\xE1dkov\xE1n\xEDm nap\u0159\xEDklad. #karti\u010Dky #bal\xED\u010Dke2 #bal\xED\u010Dek3.", CONVERT_FOLDERS_TO_DECKS: "P\u0159ev\xE9st slo\u017Eky na bal\xED\u010Dky a podbal\xED\u010Dky?", CONVERT_FOLDERS_TO_DECKS_DESC: "Toto je alternativa k tag\u016Fm karti\u010Dek viz nastaven\xED v\xFD\u0161e.", INLINE_SCHEDULING_COMMENTS: "Ulo\u017Eit pl\xE1novac\xED koment\xE1\u0159 na stejn\xFD \u0159\xE1dek jako posledn\xED polo\u017Eka karti\u010Dky?", INLINE_SCHEDULING_COMMENTS_DESC: "Zapnut\xED t\xE9to volby zp\u016Fsob\xED, \u017Ee HTML koment\xE1\u0159e nebudou rozb\xEDjet form\xE1tov\xE1n\xED list\u016F.", BURY_SIBLINGS_TILL_NEXT_DAY: "Odlo\u017Eit p\u0159\xEDbuzn\xE9 karti\u010Dky na dal\u0161\xED den?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "P\u0159\xEDbuzn\xE9 karti\u010Dky jsou karti\u010Dky generovan\xE9 z textu stejn\xE9 pozn\xE1mky nap\u0159\xEDklad cloze smaz\xE1n\xED", SHOW_CARD_CONTEXT: "Uk\xE1zat kontext v karti\u010Dce?", SHOW_CARD_CONTEXT_DESC: "nap\u0159\xEDklad Titulek > Nadpis1 > Podnadpis > ... > Podnadpis", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "V\xFD\u0161ka karti\u010Dek v procentech", CARD_MODAL_SIZE_PERCENT_DESC: "M\u011Blo by b\xFDt nastaveno na 100% na mobilu nebo kdy\u017E pou\u017E\xEDv\xE1te velk\xE9 obr\xE1zky", RESET_DEFAULT: "Resetovat v\xFDchoz\xED nastaven\xED", CARD_MODAL_WIDTH_PERCENT: "\u0160\xED\u0159ka karti\u010Dek v procentech", RANDOMIZE_CARD_ORDER: "N\xE1hodn\u011B zm\u011Bnit po\u0159ad\xED karti\u010Dek b\u011Bhem revize?", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "Vypnout cloze karti\u010Dky?", CONVERT_HIGHLIGHTS_TO_CLOZES: "P\u0159ev\xE9st ==zv\xFDrazn\u011Bn\xED== na clozes?", CONVERT_BOLD_TEXT_TO_CLOZES: "P\u0159ev\xE9st **tu\u010Dn\xFD text** na clozes?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "P\u0159ev\xE9st {{slo\u017Een\xE9 z\xE1vorky}} na clozes?", CLOZE_PATTERNS: "Cloze vzory", CLOZE_PATTERNS_DESC: 'Zadejte cloze vzory odd\u011Blen\xE9 od\u0159\xE1dkov\xE1n\xEDm. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Odd\u011Blova\u010D pro inline karti\u010Dky", FIX_SEPARATORS_MANUALLY_WARNING: "Pozor. Jakmile toto zm\u011Bn\xEDte, budete muset ru\u010Dn\u011B upravit v\u0161echny existuj\xEDc\xED karti\u010Dky.", INLINE_REVERSED_CARDS_SEPARATOR: "Odd\u011Blova\u010D pro oto\u010Den\xE9 inline karti\u010Dky", MULTILINE_CARDS_SEPARATOR: "Odd\u011Blova\u010D pro v\xEDce\u0159\xE1dkov\xE9 karti\u010Dky", MULTILINE_REVERSED_CARDS_SEPARATOR: "Odd\u011Blova\u010D pro v\xEDce\u0159\xE1dkove oto\u010Den\xE9 karti\u010Dky", MULTILINE_CARDS_END_MARKER: "Znaky ozna\u010Duj\xEDc\xED konec clozes a v\xEDce\u0159\xE1dkov\xFDch flash karet", NOTES: "Pozn\xE1mky", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Enable note review pane on startup", TAGS_TO_REVIEW: "Tag pro revizi", TAGS_TO_REVIEW_DESC: "Zadejte tagy odd\u011Blen\xE9 mezerami nebo od\u0159\xE1dkov\xE1n\xEDm nap\u0159\xEDklad #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "Otev\u0159\xEDt n\xE1hodnou pozn\xE1mku pro revizi", OPEN_RANDOM_NOTE_DESC: "Pokud toto vypnete, pozn\xE1mky budou \u0159azeny dle d\u016Fle\u017Eitosti (PageRank).", AUTO_NEXT_NOTE: "Otev\u0159\xEDt automaticky dal\u0161\xED pozn\xE1mku po dokon\u010Den\xED revize", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Povolte mo\u017Enosti revize v nab\xEDdce souboru (nap\u0159. Revize: Jednoduch\xE9, Dobr\xE9, T\u011B\u017Ek\xE9)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Pokud v nab\xEDdce souboru zak\xE1\u017Eete mo\u017Enosti revize, m\u016F\u017Eete sv\xE9 pozn\xE1mky revidovat pomoc\xED p\u0159\xEDkaz\u016F pluginu a, pokud jste je definovali, pomoc\xED p\u0159i\u0159azen\xFDch kl\xE1vesov\xFDch zkratek.", MAX_N_DAYS_REVIEW_QUEUE: "Maxim\xE1ln\xED po\u010Det dn\xED zobrazen\xFDch v prav\xE9m panelu", MIN_ONE_DAY: "Po\u010Det dn\xED mus\xED b\xFDt minim\xE1ln\u011B 1.", VALID_NUMBER_WARNING: "Pros\xEDm zadejte validn\xED \u010D\xEDslo.", UI: "P\u0159edvolby u\u017Eivatelsk\xE9ho rozhran\xED", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Stromy bal\xED\u010Dky by m\u011Bly b\xFDt zpo\u010D\xE1tku zobrazeny jako rozbalen\xE9", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Vypn\u011Bte toto, chcete-li sbalit vno\u0159en\xE9 bal\xED\u010Dky na stejn\xE9 kart\u011B. To je u\u017Eite\u010Dn\xE9, pokud m\xE1te karti\u010Dky, kter\xE9 pat\u0159\xED k mnoha bal\xED\u010Dk\u016Fm ve stejn\xE9m souboru.", ALGORITHM: "Algoritmus", CHECK_ALGORITHM_WIKI: 'Pro v\xEDce informac\xED jd\u011Bte na popis algoritmu.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Z\xE1kladn\xED slo\u017Eitost", BASE_EASE_DESC: "minimum = 130, nejl\xE9pe p\u0159ibli\u017En\u011B 250.", BASE_EASE_MIN_WARNING: "Z\xE1kladn\xED slo\u017Eitost mus\xED b\xFDt minim\xE1ln\u011B 130.", LAPSE_INTERVAL_CHANGE: "Zm\u011Bna intervalu pokud karti\u010Dku/pozn\xE1mku ozna\u010D\xEDte jako slo\u017Eitou", LAPSE_INTERVAL_CHANGE_DESC: "nov\xFD_inteval = star\xFD_interval * zm\u011Bna_intevalu / 100.", EASY_BONUS: "Bonus pro jednoduch\xE9", EASY_BONUS_DESC: "Tento bonus umo\u017E\u0148uje nastavit rozd\xEDl intervalu mezi jednoduch\xFDmi a dobr\xFDmi karti\u010Dkami/pozn\xE1mkami (minimum = 100%).", EASY_BONUS_MIN_WARNING: "Bonus pro jednoduchost mus\xED b\xFDt minim\xE1ln\u011B 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximum interval in days", MAX_INTERVAL_DESC: "Umo\u017E\u0148uje nastavit horn\xED limit pro interval (defaultn\u011B = 100 let).", MAX_INTERVAL_MIN_WARNING: "Maxim\xE1ln\xED interval mus\xED b\xFDt alespo\u0148 1 den.", MAX_LINK_CONTRIB: "Maxim\xE1ln\xED p\u0159\xEDsp\u011Bv\u011Bk prolinkov\xE1n\xED", MAX_LINK_CONTRIB_DESC: "Maxim\xE1ln\xED p\u0159\xEDsp\u011Bvek v\xE1\u017Een\xE9 slo\u017Eitosti prolinkovan\xFDch pozn\xE1mek pou\u017Eit\xFD pro ur\u010Den\xED po\u010D\xE1te\u010Dn\xED slo\u017Eitosti.", LOGGING: "Zaznamen\xE1v\xE1m", DISPLAY_SCHEDULING_DEBUG_INFO: "Zobrazit informace pro lad\u011Bn\xED na v\xFDvoj\xE1\u0159sk\xE9 konzoli", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Fronta pozn\xE1mek k revizi", CLOSE: "Uzav\u0159en\xE9", NEW: "Nov\xE9", YESTERDAY: "V\u010Dera", TODAY: "Dnes", TOMORROW: "Z\xEDtra", // stats-modal.tsx STATS_TITLE: "Statistiky", MONTH: "M\u011Bs\xEDc", QUARTER: "\u010Ctvrtlet\xED", YEAR: "Rok", LIFETIME: "Celkov\u011B", FORECAST: "P\u0159edpov\u011B\u010F", FORECAST_DESC: "Celkov\xFD po\u010Det karti\u010Dek, kter\xFDm vypr\u0161\xED term\xEDn", SCHEDULED: "Napl\xE1nov\xE1no", DAYS: "Dn\xED", NUMBER_OF_CARDS: "Po\u010Det karti\u010Dek", REVIEWS_PER_DAY: "Pr\u016Fm\u011Br: ${avg} revize/den", INTERVALS: "Intervaly", INTERVALS_DESC: "Doba, za kterou bude znovu zobrazeno k revize", COUNT: "Po\u010Det", INTERVALS_SUMMARY: "Pr\u016Fm\u011Brn\xFD interval: ${avg}, Nejdel\u0161\xED interval: ${longest}", EASES: "Slo\u017Eitost", EASES_SUMMARY: "Pr\u016Fm\u011Brn\xE1 slo\u017Eitost: ${avgEase}", EASE: "Ease", CARD_TYPES: "Typy karti\u010Dek", CARD_TYPES_DESC: "Obsahuje i odlo\u017Een\xE9 karti\u010Dky (pokud existuj\xED)", CARD_TYPE_NEW: "Nov\xE1", CARD_TYPE_YOUNG: "Mlad\xE1", CARD_TYPE_MATURE: "Dosp\u011Bl\xE1", CARD_TYPES_SUMMARY: "Karti\u010Dek celkem: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/da.ts var da_default = {}; // src/lang/locale/de.ts var de_default = { // flashcard-modal.tsx DECKS: "Stapel", DUE_CARDS: "Anstehende Karten", NEW_CARDS: "Neue Karten", TOTAL_CARDS: "Alle Karten", BACK: "Zur\xFCck", SKIP: "\xDCberspringen", EDIT_CARD: "Karte bearbeiten", RESET_CARD_PROGRESS: "Kartenfortschritt zur\xFCcksetzten", HARD: "Schwer", GOOD: "Gut", EASY: "Einfach", SHOW_ANSWER: "Zeige Antwort", CARD_PROGRESS_RESET: "Kartenfortschritt wurde zur\xFCckgesetzt.", SAVE: "Speichern", CANCEL: "Abbrechen", NO_INPUT: "Keine Eingabe erhalten.", CURRENT_EASE_HELP_TEXT: "Aktuelle Schwierigkeit: ", CURRENT_INTERVAL_HELP_TEXT: "Aktueller Intervall: ", CARD_GENERATED_FROM: "Erstellt von: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Notiz zur Wiederholung \xF6ffnen", REVIEW_CARDS: "Lernkarten wiederholen", REVIEW_DIFFICULTY_FILE_MENU: "Notizen wiederholen als: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Notizen wiederholen als: ${difficulty}", REVIEW_ALL_CARDS: "Alle Lernkarten wiederholen", CRAM_ALL_CARDS: "W\xE4hle ein Stapel zum pauken", REVIEW_CARDS_IN_NOTE: "Lernkarten in dieser Notiz wiederholen", CRAM_CARDS_IN_NOTE: "Lernkarten in dieser Notiz pauken.", VIEW_STATS: "Statistiken anzeigen", OPEN_REVIEW_QUEUE_VIEW: "\xD6ffne \xDCberpr\xFCfungswarteschlage in der Seitenleiste", STATUS_BAR: "Wiederholung: ${dueNotesCount} Notiz(en), ${dueFlashcardsCount} Karte(n) anstehend", SYNC_TIME_TAKEN: "Synchronisierung dauerte ${t}ms", NOTE_IN_IGNORED_FOLDER: "Notiz befindet sich in einem ausgeschlossenen Ordner (siehe Einstellungen).", PLEASE_TAG_NOTE: "Bitte die Notiz f\xFCr Wiederholungen entsprechend taggen (siehe Einstellungen).", RESPONSE_RECEIVED: "Antwort erhalten.", NO_DECK_EXISTS: "Kein Stapel f\xFCr ${deckName} gefunden.", ALL_CAUGHT_UP: "Yuhu! Alles geschafft! :D.", // scheduling.ts DAYS_STR_IVL: "${interval} Tag(e)", MONTHS_STR_IVL: "${interval} Monat(e)", YEARS_STR_IVL: "${interval} Jahr(e)", DAYS_STR_IVL_MOBILE: "${interval}t", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}j", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Weitere Informationen gibt es im Wiki (english).', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Ausgeschlossene Ordner", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Lernkarten", FLASHCARD_EASY_LABEL: "Einfach Knopf Text", FLASHCARD_GOOD_LABEL: "Gut Knopf Text", FLASHCARD_HARD_LABEL: "Schwer Knopf Text", FLASHCARD_GOOD_DESC: 'Passe die Beschriftung f\xFCr "Gut" Knopf an', FLASHCARD_EASY_DESC: 'Passe die Beschriftung f\xFCr "Einfach" Knopf an', FLASHCARD_HARD_DESC: 'Passe die Beschriftung f\xFCr "Schwer" Knopf an', REVIEW_BUTTON_DELAY: "Druckknopfverz\xF6gerung (ms)", REVIEW_BUTTON_DELAY_DESC: "F\xFCgt den \xDCberpr\xFCfungsschaltfl\xE4chen (\u201EEinfach\u201C, \u201EGut\u201C, \u201ESchwer\u201C, \u201EAntwort anzeigen\u201C) eine Verz\xF6gerung hinzu, bevor sie erneut gedr\xFCckt werden k\xF6nnen.", FLASHCARD_TAGS: "Lernkarten Tags", FLASHCARD_TAGS_DESC: "Mehrere Tags mit Leerzeichen oder Zeilenumbr\xFCchen getrennt angeben. Bsp. #karte #stapel2 #stapel3.", CONVERT_FOLDERS_TO_DECKS: "Ordner in Stapel und Substapel umwandeln?", CONVERT_FOLDERS_TO_DECKS_DESC: 'Eine Alternative zur oberen "Lernkarten Tags" Option.', INLINE_SCHEDULING_COMMENTS: "Den Fortschritt in der gleichen Zeile wie die letzte Zeile einer Lernkartei speichern?", INLINE_SCHEDULING_COMMENTS_DESC: "Wenn aktiviert, wird der HTML Kommentar die umgebende Liste nicht aufbrechen.", BURY_SIBLINGS_TILL_NEXT_DAY: "Verwandte Karten auf den n\xE4chsten Tag verlegen?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Verwandte Karten sind aus der gleichen Karte generiert worden (z.B. L\xFCckentextkarten oder beidseitige Karten).", SHOW_CARD_CONTEXT: "Kontext in den Karten anzeigen?", SHOW_CARD_CONTEXT_DESC: "Bsp. Titel > \xDCberschrift 1 > Sektion > ... > Untersektion", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "H\xF6he der Lernkartei in Prozent", CARD_MODAL_SIZE_PERCENT_DESC: "Auf kleinen Bildschirmen (z.B. Smartphones) oder bei sehr grossen Bildern sollte dieser Wert auf 100% gesetzt werden.", RESET_DEFAULT: "Standardeinstellung wiederherstellen", CARD_MODAL_WIDTH_PERCENT: "Breite einer Lernkarte in Prozent", RANDOMIZE_CARD_ORDER: "W\xE4hrend der Wiederhoung die Reihenfolge zuf\xE4llig mischen?", REVIEW_CARD_ORDER_WITHIN_DECK: "Reihenfolge der Karten innerhalb eines Stapels w\xE4hrend der Wiederholung", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentielle Reihenfolge innerhalb eines Stapels (Alle neuen Karten zuerst)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentielle Reihenfolge innerhalb eines Stapels (Alle f\xE4lligen Karten zuerst)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Zuf\xE4llige Reihenfolge innerhalb eines Stapels (Alle neuen Karten zuerst)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Zuf\xE4llige Reihenfolge innerhalb eines Stapels (Alle f\xE4lligen Karten zuerst)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Zuf\xE4llige Karte von zuf\xE4lligem Stapel", REVIEW_DECK_ORDER: "Reihenfolge der Stapel w\xE4hrend der Wiederholung", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentielle Reihenfolge (sobald alle Karten im vorherigen Stapel wiederholt wurden)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Zuf\xE4llige Reihenfolge (sobald alle Karten im vorherigen Stapel wiederholt wurden)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Zuf\xE4llige Karte von zuf\xE4lligem Stapel", DISABLE_CLOZE_CARDS: "L\xFCckentextkarten deaktivieren?", CONVERT_HIGHLIGHTS_TO_CLOZES: "==Hervorgehobenen== Text in L\xFCckentextkarten umwandeln?", CONVERT_BOLD_TEXT_TO_CLOZES: "**Fettgedruckten** Text in L\xFCckentextkarten umwandeln?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{Geschweifte Klammern}} Text in L\xFCckentextkarten umwandeln?", CLOZE_PATTERNS: "L\xFCckentextmuster", CLOZE_PATTERNS_DESC: 'Geben Sie L\xFCckentextmuster durch Zeilenumbr\xFCche getrennt ein. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Trennzeichen f\xFCr einzeilige Lernkarten", FIX_SEPARATORS_MANUALLY_WARNING: "Wenn diese Einstellung ge\xE4ndert wird, dann m\xFCssen die entsprechenden Lernkarten manuell angepasst werden.", INLINE_REVERSED_CARDS_SEPARATOR: "Trennzeichen f\xFCr einzeilige beidseitige Lernkarten", MULTILINE_CARDS_SEPARATOR: "Trennzeichen f\xFCr mehrzeilige Lernkarten", MULTILINE_REVERSED_CARDS_SEPARATOR: "Trennzeichen f\xFCr mehrzeilige beidseitige Lernkarten", MULTILINE_CARDS_END_MARKER: "Zeichen, die das Ende von L\xFCckentexten und mehrzeiligen Flashcards kennzeichnen", NOTES: "Notizen", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "\xD6ffne \xDCberpr\xFCfungswarteschlage beim start", TAGS_TO_REVIEW: "Zu wiederholende Tags", TAGS_TO_REVIEW_DESC: "Mehrere Tags k\xF6nnen mit Leerzeichen oder Zeilenumbr\xFCchen getrennt angegeben werden. Bsp. #karte #tag1 #tag2.", OPEN_RANDOM_NOTE: "Zuf\xE4llige Karten wiederholen", OPEN_RANDOM_NOTE_DESC: "Wenn dies deaktiviert wird, dann werden die Notizen nach Wichtigkeit wiederholt (PageRank).", AUTO_NEXT_NOTE: "Nach einer Wiederholung automatisch die n\xE4chste Karte \xF6ffnen", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Aktiviere die \xDCberpr\xFCfungsoptionen im Dateimen\xFC (z. B. Notizen wiederholen als: Einfach, Gut, Schwer)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Wenn du die \xDCberpr\xFCfungsoptionen im Dateimen\xFC deaktivierst, kannst du deine Notizen mit den Plugin-Befehlen und, falls definiert, den zugeh\xF6rigen Tastenkombinationen \xFCberpr\xFCfen.", MAX_N_DAYS_REVIEW_QUEUE: "Maximale Anzahl anstehender Notizen, die im rechten Fensterbereich angezeigt werden", MIN_ONE_DAY: "Anzahl der Tage muss mindestens 1 sein.", VALID_NUMBER_WARNING: "Bitte eine g\xFCltige Zahl eingeben.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Stapelverzeichnis soll beim \xF6ffnen erweitert angezeigt werden", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Deaktivieren Sie dies, um verschachtelte Stapel in derselben Karte zu reduzieren. N\xFCtzlich, wenn Sie Karten haben, die zu vielen Stapeln in derselben Datei geh\xF6ren.", ALGORITHM: "Algorithmus", CHECK_ALGORITHM_WIKI: 'Weiterf\xFChrende Informationen: Implementierung des Algorithmus (english).', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Basis der Schwierigkeit", BASE_EASE_DESC: "Minimum ist 130. Empfohlen wird ca. 250.", BASE_EASE_MIN_WARNING: "Basis der Schwierigkeit muss mindestens 130 sein.", LAPSE_INTERVAL_CHANGE: "Anpassungsfaktor des Intervalls wenn eine Notiz / Karte 'Schwer' abgeschlossen wird", LAPSE_INTERVAL_CHANGE_DESC: "neuesIntervall = altesIntervall * anpassungsfaktor / 100.", EASY_BONUS: "Einfachheit-Bonus", EASY_BONUS_DESC: "Der Einfachheit-Bonus gibt an um welchen Faktor (in Prozent) das Intervall l\xE4nger sein soll, wenn eine Notiz / Karte 'Einfach' statt 'Gut' abgeschlossen wird. Minimum ist 100%.", EASY_BONUS_MIN_WARNING: "Der Einfachheit-Bonus muss mindestens 100 sein.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximale Intervall in Tagen", MAX_INTERVAL_DESC: "Das maximale Intervall (in Tagen) f\xFCr Wiederholungen. Standard sind 100 Jahre.", MAX_INTERVAL_MIN_WARNING: "Das maximale Interall muss mindestens ein Tag sein.", MAX_LINK_CONTRIB: "Maximaler Einfluss von Links", MAX_LINK_CONTRIB_DESC: "Maximaler Einfluss der Einfachheiten verlinkter Notizen zur gewichteten initialen Einfachheit einer neuen Lernkarte.", LOGGING: "Protokollierung", DISPLAY_SCHEDULING_DEBUG_INFO: "Informationen zum Debugging in der Entwicklerkonsole anzeigen", DISPLAY_PARSER_DEBUG_INFO: "Informationen zum parser Debugging in der Entwicklerkonsole anzeigen", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Anstehende Notizen zur Wiederholung", CLOSE: "Schliessen", NEW: "Neu", YESTERDAY: "Gestern", TODAY: "Heute", TOMORROW: "Morgen", // stats-modal.tsx STATS_TITLE: "Statistiken", MONTH: "Monat", QUARTER: "Quartal", YEAR: "Jahr", LIFETIME: "Lebenslang", FORECAST: "Prognose", FORECAST_DESC: "Anzahl der k\xFCnftig anstehenden Karten", SCHEDULED: "Anstehend", DAYS: "Tage", NUMBER_OF_CARDS: "Anzahl der Karten", REVIEWS_PER_DAY: "Durchschnitt: ${avg} Wiederholungen/Tag", INTERVALS: "Intervalle", INTERVALS_DESC: "Intervalle bis Wiederholungen anstehen", COUNT: "Anzahl", INTERVALS_SUMMARY: "Durchschnittliches Intervall: ${avg}, L\xE4ngstes Intervall: ${longest}", EASES: "Schwierigkeit", EASES_SUMMARY: "Durchschnittliche Schwierigkeit: ${avgEase}", EASE: "Ease", CARD_TYPES: "Kategorisierung", CARD_TYPES_DESC: "Verlegte Karten eingeschlossen", CARD_TYPE_NEW: "Neu", CARD_TYPE_YOUNG: "Jung", CARD_TYPE_MATURE: "Ausgereift", CARD_TYPES_SUMMARY: "Insgesamt ${totalCardsCount} Karten", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/en.ts var en_default = { // flashcard-modal.tsx DECKS: "Decks", DUE_CARDS: "Due Cards", NEW_CARDS: "New Cards", TOTAL_CARDS: "Total Cards", BACK: "Back", SKIP: "Skip", EDIT_CARD: "Edit Card", RESET_CARD_PROGRESS: "Reset card's progress", HARD: "Hard", GOOD: "Good", EASY: "Easy", SHOW_ANSWER: "Show Answer", CARD_PROGRESS_RESET: "Card's progress has been reset.", SAVE: "Save", CANCEL: "Cancel", NO_INPUT: "No input provided.", CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Open a note for review", REVIEW_CARDS: "Review flashcards", REVIEW_DIFFICULTY_FILE_MENU: "Review: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Review note as ${difficulty}", CRAM_ALL_CARDS: "Select a deck to cram", REVIEW_ALL_CARDS: "Review flashcards from all notes", REVIEW_CARDS_IN_NOTE: "Review flashcards in this note", CRAM_CARDS_IN_NOTE: "Cram flashcards in this note", VIEW_STATS: "View statistics", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Review: ${dueNotesCount} note(s), ${dueFlashcardsCount} card(s) due", SYNC_TIME_TAKEN: "Sync took ${t}ms", NOTE_IN_IGNORED_FOLDER: "Note is saved under ignored folder (check settings).", PLEASE_TAG_NOTE: "Please tag the note appropriately for reviewing (in settings).", RESPONSE_RECEIVED: "Response received.", NO_DECK_EXISTS: "No deck exists for ${deckName}", ALL_CAUGHT_UP: "You're all caught up now :D.", // scheduling.ts DAYS_STR_IVL: "${interval} day(s)", MONTHS_STR_IVL: "${interval} month(s)", YEARS_STR_IVL: "${interval} year(s)", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}y", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'For more information, check the wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Folders to ignore", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Flashcards", FLASHCARD_EASY_LABEL: "Easy Button Text", FLASHCARD_GOOD_LABEL: "Good Button Text", FLASHCARD_HARD_LABEL: "Hard Button Text", FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button', FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button', FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Flashcard tags", FLASHCARD_TAGS_DESC: "Enter tags separated by spaces or newlines i.e. #flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "Convert folders to decks and subdecks", CONVERT_FOLDERS_TO_DECKS_DESC: "This is an alternative to the Flashcard tags option above.", INLINE_SCHEDULING_COMMENTS: "Save scheduling comment on the same line as the flashcard's last line?", INLINE_SCHEDULING_COMMENTS_DESC: "Turning this on will make the HTML comments not break list formatting.", BURY_SIBLINGS_TILL_NEXT_DAY: "Bury sibling cards until the next day", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Siblings are cards generated from the same card text i.e. cloze deletions", SHOW_CARD_CONTEXT: "Show context in cards", SHOW_CARD_CONTEXT_DESC: "i.e. Title > Heading 1 > Subheading > ... > Subheading", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Flashcard Height Percentage", CARD_MODAL_SIZE_PERCENT_DESC: "Should be set to 100% on mobile or if you have very large images", RESET_DEFAULT: "Reset to default", CARD_MODAL_WIDTH_PERCENT: "Flashcard Width Percentage", RANDOMIZE_CARD_ORDER: "Randomize card order during review?", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "Disable cloze cards?", CONVERT_HIGHLIGHTS_TO_CLOZES: "Convert ==highlights== to clozes", CONVERT_BOLD_TEXT_TO_CLOZES: "Convert **bolded text** to clozes", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convert {{curly brackets}} to clozes", CLOZE_PATTERNS: "Cloze Patterns", CLOZE_PATTERNS_DESC: 'Enter cloze patterns separated by newlines. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Separator for inline flashcards", FIX_SEPARATORS_MANUALLY_WARNING: "Note that after changing this you have to manually edit any flashcards you already have.", INLINE_REVERSED_CARDS_SEPARATOR: "Separator for inline reversed flashcards", MULTILINE_CARDS_SEPARATOR: "Separator for multiline flashcards", MULTILINE_REVERSED_CARDS_SEPARATOR: "Separator for multiline reversed flashcards", MULTILINE_CARDS_END_MARKER: "Characters denoting the end of clozes and multiline flashcards", NOTES: "Notes", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Enable note review pane on startup", TAGS_TO_REVIEW: "Tags to review", TAGS_TO_REVIEW_DESC: "Enter tags separated by spaces or newlines i.e. #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "Open a random note for review", OPEN_RANDOM_NOTE_DESC: "When you turn this off, notes are ordered by importance (PageRank).", AUTO_NEXT_NOTE: "Open next note automatically after a review", MAX_N_DAYS_REVIEW_QUEUE: "Maximum number of days to display on note review panel", MIN_ONE_DAY: "The number of days must be at least 1.", VALID_NUMBER_WARNING: "Please provide a valid number.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Enable the review options in the file menu (e.g. Review: Easy, Good, Hard)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "If you disable the review options in the file menu, you can review your notes using the plugin commands and, if you defined them, the associated command hotkeys.", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Deck trees should be initially displayed as expanded", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Turn this off to collapse nested decks in the same card. Useful if you have cards which belong to many decks in the same file.", ALGORITHM: "Algorithm", CHECK_ALGORITHM_WIKI: 'For more information, check the algorithm details.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Base ease", BASE_EASE_DESC: "minimum = 130, preferrably approximately 250.", BASE_EASE_MIN_WARNING: "The base ease must be at least 130.", LAPSE_INTERVAL_CHANGE: "Interval change when you review a flashcard/note as hard", LAPSE_INTERVAL_CHANGE_DESC: "newInterval = oldInterval * intervalChange / 100.", EASY_BONUS: "Easy Bonus", EASY_BONUS_DESC: "The easy bonus allows you to set the difference in intervals between answering Good and Easy on a flashcard/note (minimum = 100%).", EASY_BONUS_MIN_WARNING: "The easy bonus must be at least 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximum interval in days", MAX_INTERVAL_DESC: "Allows you to place an upper limit on the interval (default = 100 years).", MAX_INTERVAL_MIN_WARNING: "The maximum interval must be at least 1 day.", MAX_LINK_CONTRIB: "Maximum link contribution", MAX_LINK_CONTRIB_DESC: "Maximum contribution of the weighted ease of linked notes to the initial ease.", LOGGING: "Logging", DISPLAY_SCHEDULING_DEBUG_INFO: "Show the scheduler's debugging information on the developer console", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Notes Review Queue", CLOSE: "Close", NEW: "New", YESTERDAY: "Yesterday", TODAY: "Today", TOMORROW: "Tomorrow", // stats-modal.tsx STATS_TITLE: "Statistics", MONTH: "Month", QUARTER: "Quarter", YEAR: "Year", LIFETIME: "Lifetime", FORECAST: "Forecast", FORECAST_DESC: "The number of cards due in the future", SCHEDULED: "Scheduled", DAYS: "Days", NUMBER_OF_CARDS: "Number of cards", REVIEWS_PER_DAY: "Average: ${avg} reviews/day", INTERVALS: "Intervals", INTERVALS_DESC: "Delays until reviews are shown again", COUNT: "Count", INTERVALS_SUMMARY: "Average interval: ${avg}, Longest interval: ${longest}", EASES: "Eases", EASES_SUMMARY: "Average ease: ${avgEase}", EASE: "Ease", CARD_TYPES: "Card Types", CARD_TYPES_DESC: "This includes buried cards as well, if any", CARD_TYPE_NEW: "New", CARD_TYPE_YOUNG: "Young", CARD_TYPE_MATURE: "Mature", CARD_TYPES_SUMMARY: "Total cards: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/en-gb.ts var en_gb_default = {}; // src/lang/locale/es.ts var es_default = { // flashcard-modal.tsx DECKS: "Mazos", DUE_CARDS: "Tarjetas Vencidas", NEW_CARDS: "Tarjetas Nuevas", TOTAL_CARDS: "Tarjetas Totales", BACK: "Atr\xE1s", SKIP: "Saltar", EDIT_CARD: "Editar Tarjeta", RESET_CARD_PROGRESS: "Reiniciar progreso de la tarjeta", HARD: "Dif\xEDcil", GOOD: "Bien", EASY: "F\xE1cil", SHOW_ANSWER: "Mostrar Respuesta", CARD_PROGRESS_RESET: "El progreso de la tarjeta se ha reiniciado.", SAVE: "Guardar", CANCEL: "Cancelar", NO_INPUT: "Se ha prove\xEDdo entrada.", CURRENT_EASE_HELP_TEXT: "Facilidad Actual: ", CURRENT_INTERVAL_HELP_TEXT: "Intervalo Actual: ", CARD_GENERATED_FROM: "Generado Desde: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Abrir nota para revisi\xF3n", REVIEW_CARDS: "Revisar Tarjetas", REVIEW_DIFFICULTY_FILE_MENU: "Revisar: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Revisar nota como ${difficulty}", CRAM_ALL_CARDS: "Selecciona un mazo a memorizar", REVIEW_ALL_CARDS: "Revisar tarjetas de todas las notas", REVIEW_CARDS_IN_NOTE: "Revisar tarjetas en esta nota", CRAM_CARDS_IN_NOTE: "Memorizar tarjetas en esta nota", VIEW_STATS: "Ver estad\xEDsticas", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Revisar: ${dueNotesCount} nota(s), ${dueFlashcardsCount} tarjetas vencidas", SYNC_TIME_TAKEN: "La sincronizaci\xF3n tom\xF3 ${t} milisegundos", NOTE_IN_IGNORED_FOLDER: "La nota est\xE1 guardada en un directorio ignorado (revisa los ajustes).", PLEASE_TAG_NOTE: "Por favor etiquete apropiadamente la nota para revisi\xF3n (en los ajustes).", RESPONSE_RECEIVED: "Respuesta Recibida", NO_DECK_EXISTS: "No existen mazos para: ${deckName}", ALL_CAUGHT_UP: "\xA1Est\xE1s al d\xEDa! \u{1F603}", // scheduling.ts DAYS_STR_IVL: "${interval} d\xEDa(s)", MONTHS_STR_IVL: "${interval} mes(es)", YEARS_STR_IVL: "${interval} a\xF1o(s)", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}a", // settings.ts SETTINGS_HEADER: "Extensi\xF3n de Repetici\xF3n Espaciada", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Para m\xE1s informaci\xF3n revisa la wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Directorios a ignorar", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Tarjetas de Memorizaci\xF3n", FLASHCARD_EASY_LABEL: "Texto del bot\xF3n: F\xE1cil", FLASHCARD_GOOD_LABEL: "Texto del bot\xF3n: Bien", FLASHCARD_HARD_LABEL: "Texto del bot\xF3n: Dif\xEDcil", FLASHCARD_EASY_DESC: "Personalize la etiqueta para el bot\xF3n: F\xE1cil", FLASHCARD_GOOD_DESC: "Personalize la etiqueta para el bot\xF3n: Bien", FLASHCARD_HARD_DESC: "Personalize la etiqueta para el bot\xF3n: Dif\xEDcil", REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Etiquetas de las Tarjetas de Memorizaci\xF3n", FLASHCARD_TAGS_DESC: "Escriba las etiquetas separadas por espacios o saltos de l\xEDnea, por ejemplo, #memorizar #mazo2 #mazo3", CONVERT_FOLDERS_TO_DECKS: "\xBFConvertir directorios a mazos y submazos?", CONVERT_FOLDERS_TO_DECKS_DESC: "Esta es una opci\xF3n alternativa a las etiquetas de las Tarjetas de Memorizaci\xF3n.", INLINE_SCHEDULING_COMMENTS: "\xBFGuardar el comentario para programaci\xF3n de las tarjetas en la \xFAltima l\xEDnea?", INLINE_SCHEDULING_COMMENTS_DESC: "Activar esto har\xE1 que los comentarios HTML no rompan el formato de las listas.", BURY_SIBLINGS_TILL_NEXT_DAY: "\xBFEnterrar tarjetas hermanas hasta el siguiente d\xEDa?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Los hermanos son tarjetas generadas del mismo texto de la tarjeta, por ejemplo, deletreos de huecos (cloze deletions en ingl\xE9s)", SHOW_CARD_CONTEXT: "\xBFMostrar contexto en las tarjetas?", SHOW_CARD_CONTEXT_DESC: "Por Ejemplo: T\xEDtulo > Cabecera > Sub-Cabecera > ... > Sub-Cabecera", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Porcentaje de la altura de las tarjetas de memoria", CARD_MODAL_SIZE_PERCENT_DESC: "Deber\xEDa ser establecido en 100% si tienes im\xE1genes grandes", RESET_DEFAULT: "Reiniciar a la configuraci\xF3n por defecto", CARD_MODAL_WIDTH_PERCENT: "Porcentaje del ancho de las tarjetas de memoria", RANDOMIZE_CARD_ORDER: "\xBFAleatorizar el orden de las tarjetas para revisi\xF3n?", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "\xBFDeshabilitar deletreo de huecos en las tarjetas?", CONVERT_HIGHLIGHTS_TO_CLOZES: "\xBFConvertir ==resaltados== a deletreo de huecos?", CONVERT_BOLD_TEXT_TO_CLOZES: "\xBFConvertir **texto en negrita** a deletreo de huecos?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "\xBFConvertir {{llaves rizadas}} a deletreo de huecos?", CLOZE_PATTERNS: "Patrones de deletreo de huecos", CLOZE_PATTERNS_DESC: 'Escriba los patrones de deletreo de huecos separados por saltos de l\xEDnea. . Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Separador de tarjetas de memorizaci\xF3n en l\xEDnea", FIX_SEPARATORS_MANUALLY_WARNING: "Note que despu\xE9s de cambiar este ajuste, tendr\xE1 que cambiar manualmente todas las notas que tenga.", INLINE_REVERSED_CARDS_SEPARATOR: "Separador de tarjetas de memorizaci\xF3n para tarjetas de notas invertidas", MULTILINE_CARDS_SEPARATOR: "Separador para tarjetas de memorizaci\xF3n multil\xEDnea", MULTILINE_REVERSED_CARDS_SEPARATOR: "Separador para tarjetas de memorizaci\xF3n multil\xEDnea invertidas", MULTILINE_CARDS_END_MARKER: "Caracteres que denotan el fin de los clozes y tarjetas did\xE1cticas de varias l\xEDneas", NOTES: "Notes", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Activar panel de revisi\xF3n de notas al arrancar", TAGS_TO_REVIEW: "Etiquetas a revisar", TAGS_TO_REVIEW_DESC: "Escriba las etiquetas separadas por espacios o saltos de l\xEDneas, por ejemplo, #revisi\xF3n #etiqueta2 #etiqueta3.", OPEN_RANDOM_NOTE: "Abrir una nota al azar para revisar", OPEN_RANDOM_NOTE_DESC: "Cuando deshabilita esto, las notas son ordenadas por importancia (Algoritmo PageRank).", AUTO_NEXT_NOTE: "Abrir la siguiente nota autom\xE1ticamente despu\xE9s de una revisi\xF3n", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Habilita las opciones de revisi\xF3n en el men\xFA Archivo (por ejemplo: Revisar: F\xE1cil, Bien, Dif\xEDcil)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Si desactivas las opciones de revisi\xF3n en el men\xFA Archivo, puedes revisar tus notas usando los comandos del plugin y, si los definiste, las teclas r\xE1pidas asociadas.", MAX_N_DAYS_REVIEW_QUEUE: "N\xFAmero m\xE1ximo de d\xEDas a mostrar en el panel derecho.", MIN_ONE_DAY: "El n\xFAmero de d\xEDas debe ser al menos uno.", VALID_NUMBER_WARNING: "Por favor especifique un n\xFAmero v\xE1lido.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Los \xE1rboles de mazos deber\xEDan ser expandidos al inicio.", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Desactiva esto para contraer mazos anidados en la misma tarjeta. \xDAtil si tienes tarjetas que pertenecen a muchos mazos en el mismo archivo.", ALGORITHM: "Algoritmo", CHECK_ALGORITHM_WIKI: 'Para m\xE1s informaci\xF3n, revisa la implementaci\xF3n del algoritmo.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Base ease", BASE_EASE_DESC: "El m\xEDnimo es 130, es preferible que est\xE9 aproximado a 250.", BASE_EASE_MIN_WARNING: "La facilidad base de las tarjetas debe ser al menos 130.", LAPSE_INTERVAL_CHANGE: "El intervalo cambiar\xE1 cuando se revise una tarjeta o nota como Dif\xEDcil.", LAPSE_INTERVAL_CHANGE_DESC: "NuevoInterval = ViejoIntervalo * CambioDeIntervalo / 100.", EASY_BONUS: "Bonificaci\xF3n para F\xE1cil", EASY_BONUS_DESC: "La bonificaci\xF3n para F\xE1cil te permite establecer la diferencia entre intervalos al responder Bien y F\xE1cil en las tarjetas o notas (m\xEDnimo = 100%).", EASY_BONUS_MIN_WARNING: "El bono de facilidad debe ser al menos 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Intervalo m\xE1ximo en d\xEDas", MAX_INTERVAL_DESC: "Te permite establecer un l\xEDmite mayor en el intervalo (por defecto es de 100 a\xF1os).", MAX_INTERVAL_MIN_WARNING: "El intervalo m\xE1ximo debe ser de al menos un d\xEDa.", MAX_LINK_CONTRIB: "Contribuci\xF3n m\xE1xima de las notas vinculadas.", MAX_LINK_CONTRIB_DESC: "Contribuci\xF3n m\xE1xima de la facilidad ponderada de las notas vinculadas a la facilidad inicial.", LOGGING: "Registro", DISPLAY_SCHEDULING_DEBUG_INFO: "\xBFMostrar informaci\xF3n de depuraci\xF3n en la consola de desarrollador", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Cola de notas a revisar", CLOSE: "Cerrar", NEW: "Nuevo", YESTERDAY: "Ayer", TODAY: "Hoy", TOMORROW: "Ma\xF1ana", // stats-modal.tsx STATS_TITLE: "Estad\xEDsticas", MONTH: "Mes", QUARTER: "Trimestre o Cuatrimestre", // En Inglés: Quarter. YEAR: "A\xF1o", LIFETIME: "Tiempo de Vida", FORECAST: "Pron\xF3stico", FORECAST_DESC: "El n\xFAmero de tarjetas vencidas en el futuro", SCHEDULED: "Programado", DAYS: "D\xEDas", NUMBER_OF_CARDS: "N\xFAmero de tarjetas", REVIEWS_PER_DAY: "Carga: ${avg} Revisiones por d\xEDa", INTERVALS: "Intervalos", INTERVALS_DESC: "Retrasos hasta que las revisiones se muestren de nuevo", COUNT: "Conteo", INTERVALS_SUMMARY: "Intervalo de carga: ${avg}, Intervalo mayor: ${longest}", EASES: "Facilidad", EASES_SUMMARY: "Carga de Facilidad: ${avgEase}", EASE: "Ease", CARD_TYPES: "Tipos de tarjetas", CARD_TYPES_DESC: "Esto incluye tambi\xE9n a las tarjetas enterradas, si las hay", CARD_TYPE_NEW: "Nueva", CARD_TYPE_YOUNG: "Joven", CARD_TYPE_MATURE: "Madura", CARD_TYPES_SUMMARY: "Tarjetas Totales: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/fr.ts var fr_default = { // flashcard-modal.tsx DECKS: "Paquets", DUE_CARDS: "Cartes dues", NEW_CARDS: "Nouvelles cartes", TOTAL_CARDS: "Total de cartes", BACK: "Pr\xE9c\xE9dent", SKIP: "Sauter", EDIT_CARD: "Modifier la carte", RESET_CARD_PROGRESS: "Remettre \xE0 z\xE9ro le niveau de cette carte", HARD: "Difficile", GOOD: "Correct", EASY: "Facile", SHOW_ANSWER: "Montrer la r\xE9ponse", CARD_PROGRESS_RESET: "Le niveau de la carte a \xE9t\xE9 remis \xE0 z\xE9ro.", SAVE: "Sauvegarder", CANCEL: "Annuler", NO_INPUT: "Pas de contenu.", CURRENT_EASE_HELP_TEXT: "Facilit\xE9 actuelle : ", CURRENT_INTERVAL_HELP_TEXT: "Intervalle actuel : ", CARD_GENERATED_FROM: "G\xE9n\xE9r\xE9 depuis : ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Ouvrir une note \xE0 apprendre", REVIEW_CARDS: "Apprendre les flashcards", REVIEW_DIFFICULTY_FILE_MENU: "Apprentissage : ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Difficult\xE9 de la r\xE9vision : ${difficulty}", CRAM_ALL_CARDS: "Choisir un deck \xE0 r\xE9viser", REVIEW_ALL_CARDS: "Apprendre les flashcards dans toutes les notes", REVIEW_CARDS_IN_NOTE: "Apprendre les flashcards dans cette note", CRAM_CARDS_IN_NOTE: "R\xE9viser les flashcards dans cette note", VIEW_STATS: "Voir les statistiques", OPEN_REVIEW_QUEUE_VIEW: "Ouvrir la file d'attente des notes \xE0 apprendre dans la barre verticale", STATUS_BAR: "Apprentissage : ${dueNotesCount} note(s), ${dueFlashcardsCount} carte(s) dues", SYNC_TIME_TAKEN: "Synchronis\xE9 en ${t}ms", NOTE_IN_IGNORED_FOLDER: "La note est dans un dossier ignor\xE9 (voir param\xE8tres).", PLEASE_TAG_NOTE: "Ajoutez le bon tag \xE0 la note pour l'apprendre (dans les param\xE8tres).", RESPONSE_RECEIVED: "R\xE9ponse enregistr\xE9e.", NO_DECK_EXISTS: "Pas de paquet sous le nom ${deckName}", ALL_CAUGHT_UP: "Bravo, vous \xEAtes \xE0 jour !", // scheduling.ts DAYS_STR_IVL: "${interval} jour(s)", MONTHS_STR_IVL: "${interval} mois(s)", YEARS_STR_IVL: "${interval} an(s)", DAYS_STR_IVL_MOBILE: "${interval}j", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}a", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Dossiers", GROUP_FLASHCARD_REVIEW: "Apprentissage des flashcards", GROUP_FLASHCARD_SEPARATORS: "S\xE9parateurs de flashcards", GROUP_DATA_STORAGE: "Stockage des informations de planification", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contribuer", CHECK_WIKI: 'Pour plus d\'informations, visitez le wiki.', GITHUB_DISCUSSIONS: 'Visitez les discussions pour des questions-r\xE9ponses, des retours ou une discussion g\xE9n\xE9raliste.', GITHUB_ISSUES: 'Cr\xE9ez un ticket sur GitHub si vous trouvez un bug ou voulez demander une fonctionnalit\xE9.', GITHUB_SOURCE_CODE: 'Code source du projet disponible sur GitHub', CODE_CONTRIBUTION_INFO: 'Information sur les contributions au code', TRANSLATION_CONTRIBUTION_INFO: 'Informations sur la traduction du plugin dans votre langue', FOLDERS_TO_IGNORE: "Dossiers \xE0 ignorer", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Flashcards", FLASHCARD_EASY_LABEL: "Bouton Facile", FLASHCARD_GOOD_LABEL: "Bouton Correct", FLASHCARD_HARD_LABEL: "Bouton Difficile", FLASHCARD_EASY_DESC: "Changez le texte du bouton Facile", FLASHCARD_GOOD_DESC: "Changez le texte du bouton Correct", FLASHCARD_HARD_DESC: "Changez le texte du bouton Difficile", REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Tags des flashcards", FLASHCARD_TAGS_DESC: "Entrez les tags s\xE9par\xE9s par un espace ou une ligne i.e. #flashcards #paquet2 #paquet3.", CONVERT_FOLDERS_TO_DECKS: "Convertir les dossiers en paquets et sous-paquets ?", CONVERT_FOLDERS_TO_DECKS_DESC: "Ceci est une alternative aux tags de flashcards pr\xE9sent\xE9s ci-dessus.", INLINE_SCHEDULING_COMMENTS: "Sauvegarder le commentaire de planification dans la derni\xE8re ligne de la flashcard ?", INLINE_SCHEDULING_COMMENTS_DESC: "Activer ceci emp\xEAche les commentaires HTML de casser la mise en page des listes.", BURY_SIBLINGS_TILL_NEXT_DAY: "Enterrer les cartes s\u0153urs jusqu'au lendemain ?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Les cartes s\u0153urs sont les cartes g\xE9n\xE9r\xE9es depuis le m\xEAme texte, par exemple pour les textes \xE0 trous", SHOW_CARD_CONTEXT: "Montrer le contexte dans les cartes ?", SHOW_CARD_CONTEXT_DESC: "ex. Titre de la note > Titre 1 > Sous-titre > ... > Sous-titre", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Pourcentage de hauteur de la flashcard", CARD_MODAL_SIZE_PERCENT_DESC: "Devrait \xEAtre 100% sur mobile ou en cas de grandes images", RESET_DEFAULT: "R\xE9initialiser les param\xE8tres", CARD_MODAL_WIDTH_PERCENT: "Pourcentage de largeur de la flashcard", RANDOMIZE_CARD_ORDER: "Apprendre les cartes dans un ordre al\xE9atoire ?", REVIEW_CARD_ORDER_WITHIN_DECK: "Ordre d'affichage des cartes d'un paquet pendant les r\xE9visions", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Dans l'ordre du paquet (Nouvelles cartes d'abord)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Dans l'ordre du paquet (Cartes dues d'abord)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Al\xE9atoirement dans le paquet (Nouvelles cartes d'abord)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Al\xE9atoirement dans le paquet (Cartes dues d'abord)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Carte au hasard dans un paquet au hasard", REVIEW_DECK_ORDER: "Ordre d'affichage des paquets pendant les r\xE9visions", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "S\xE9quentiel (quand toutes les cartes du paquet pr\xE9c\xE9dent sont apprises)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Al\xE9atoire (quand toutes les cartes du paquet pr\xE9c\xE9dent sont apprises)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Carte au hasard dans un paquet au hasard", DISABLE_CLOZE_CARDS: "D\xE9sactiver les textes \xE0 trous ?", CONVERT_HIGHLIGHTS_TO_CLOZES: "Convertir ==soulignages== en trous ?", CONVERT_BOLD_TEXT_TO_CLOZES: "Convertir **gras** en trous ?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convertir {{crochets}} en trous ?", CLOZE_PATTERNS: "Cloze Patterns", CLOZE_PATTERNS_DESC: 'Enter cloze patterns separated by newlines. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "S\xE9parateur pour flashcards en une ligne", FIX_SEPARATORS_MANUALLY_WARNING: "Apr\xE8s avoir chang\xE9 ce r\xE9glage, vous devrez manuellement mettre \xE0 jour toutes vos flashcards.", INLINE_REVERSED_CARDS_SEPARATOR: "S\xE9parateur pour flashcards invers\xE9es en une ligne", MULTILINE_CARDS_SEPARATOR: "S\xE9parateur pour flashcards en plusieurs lignes", MULTILINE_REVERSED_CARDS_SEPARATOR: "S\xE9parateur pour flashcards invers\xE9es en plusieurs lignes", MULTILINE_CARDS_END_MARKER: "Caract\xE8res de fin de textes \xE0 trous ou de flashcards en plusieurs lignes", NOTES: "Notes", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Montrer le module d'apprentissage des notes au d\xE9marrage", TAGS_TO_REVIEW: "Tags \xE0 apprendre", TAGS_TO_REVIEW_DESC: "Entrez les tags s\xE9par\xE9s par un espace ou une ligne i.e. #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "Ouvrir une note \xE0 apprendre au hasard", OPEN_RANDOM_NOTE_DESC: "Si vous d\xE9sactivez cette option, les notes sont tri\xE9es par importance (PageRank).", AUTO_NEXT_NOTE: "Ouvrir la prochaine note automatiquement apr\xE8s un apprentissage", MAX_N_DAYS_REVIEW_QUEUE: "Jours maximum affich\xE9s dans la barre de droite", MIN_ONE_DAY: "Le nombre de jours doit \xEAtre au moins 1.", VALID_NUMBER_WARNING: "Entrez un nombre valide.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Enable the review options in the file menu (e.g. Review: Easy, Good, Hard)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "If you disable the review options in the file menu, you can review your notes using the plugin commands and, if you defined them, the associated command hotkeys.", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Les dossiers de paquets devraient initialement tous \xEAtre ouverts", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "D\xE9sactivez pour r\xE9duire les paquets dans la m\xEAme carte. Ce r\xE9glage est utile si vous avez des cartes qui appartiennent \xE0 beaucoup de paquets \xE0 la fois.", ALGORITHM: "Algorithme", CHECK_ALGORITHM_WIKI: `Pour en savoir plus, lisez l'impl\xE9mentation de l'algorithme.`, SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Facilit\xE9 de base", BASE_EASE_DESC: "minimum = 130, recommand\xE9 = vers 250.", BASE_EASE_MIN_WARNING: "La facilit\xE9 de base doit \xEAtre sup\xE9rieure \xE0 130.", LAPSE_INTERVAL_CHANGE: "Changement d'intervalle quand vous indiquez qu'une flashcard/note a \xE9t\xE9 difficile", LAPSE_INTERVAL_CHANGE_DESC: "nouvelIntervalle = ancienIntervalle * changementIntervalle / 100.", EASY_BONUS: "Bonus Facile", EASY_BONUS_DESC: "Le bonus Facile vous permet d'augmenter l'intervalle entre une r\xE9ponse Correct et une r\xE9ponse Facile sur une flashcard/note (minimum = 100%).", EASY_BONUS_MIN_WARNING: "Le bonus Facile doit \xEAtre au moins 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Intervalle maximum (en jours)", MAX_INTERVAL_DESC: "Vous permet de mettre une limite maximale sur l'intervalle (par d\xE9faut, 100 ans).", MAX_INTERVAL_MIN_WARNING: "L'intervalle maximum doit \xEAtre au moins 1 jour.", MAX_LINK_CONTRIB: "Contribution maximum des liens", MAX_LINK_CONTRIB_DESC: "Contribution maximum de la facilit\xE9 pond\xE9r\xE9e des notes li\xE9es \xE0 la facilit\xE9 initiale.", LOGGING: "Logging", DISPLAY_SCHEDULING_DEBUG_INFO: "Afficher les informations de d\xE9bogage dans la console de d\xE9veloppement", DISPLAY_PARSER_DEBUG_INFO: "Afficher les informations de d\xE9bogage pour le parser dans la console de d\xE9veloppement", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Cartes \xE0 apprendre", CLOSE: "Fermer", NEW: "Nouveau", YESTERDAY: "Hier", TODAY: "Aujourd'hui", TOMORROW: "Demain", // stats-modal.tsx STATS_TITLE: "Statistiques", MONTH: "Mois", QUARTER: "Trimestre", YEAR: "Ann\xE9e", LIFETIME: "Toujours", FORECAST: "Pr\xE9visions", FORECAST_DESC: "Le nombre de cartes dues dans le futur", SCHEDULED: "Planifi\xE9", DAYS: "Jours", NUMBER_OF_CARDS: "Nombre de cartes", REVIEWS_PER_DAY: "Moyenne : ${avg} apprentissages / jour", INTERVALS: "Intervalles", INTERVALS_DESC: "Dur\xE9e avant de remontrer une carte", COUNT: "Total", INTERVALS_SUMMARY: "Intervalle moyen : ${avg}. Intervalle maximum: ${longest}", EASES: "Facilit\xE9", EASES_SUMMARY: "Facilit\xE9 moyenne : ${avgEase}", EASE: "Ease", CARD_TYPES: "Types de cartes", CARD_TYPES_DESC: "Ceci inclut les cartes enterr\xE9es, s'il y en a", CARD_TYPE_NEW: "Nouvelles", CARD_TYPE_YOUNG: "En cours d'apprentissage", CARD_TYPE_MATURE: "Matures", CARD_TYPES_SUMMARY: "Total de cartes : ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/hi.ts var hi_default = {}; // src/lang/locale/id.ts var id_default = {}; // src/lang/locale/it.ts var it_default = { // flashcard-modal.tsx DECKS: "Mazzi", DUE_CARDS: "Schede da fare", NEW_CARDS: "Schede nuove", TOTAL_CARDS: "Schede totali", BACK: "Indietro", SKIP: "Salta", EDIT_CARD: "Modifica scheda", RESET_CARD_PROGRESS: "Ripristina i progressi della scheda", HARD: "Difficile", GOOD: "Buono", EASY: "Facile", SHOW_ANSWER: "Mostra risposta", CARD_PROGRESS_RESET: "I progressi della scheda sono stati ripristinati", SAVE: "Salva", CANCEL: "Cancella", NO_INPUT: "Non \xE8 stato provvisto alcun input", CURRENT_EASE_HELP_TEXT: "Difficolt\xE0 attuale: ", CURRENT_INTERVAL_HELP_TEXT: "Intervallo attuale: ", CARD_GENERATED_FROM: "Generato da: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Apri una nota per rivisita", REVIEW_CARDS: "Rivisita schede", REVIEW_DIFFICULTY_FILE_MENU: "Rivisita: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Revisita note come ${difficulty}", CRAM_ALL_CARDS: "Seleziona un mazzo da memorizzare", REVIEW_ALL_CARDS: "Seleziona schede da rivedere", REVIEW_CARDS_IN_NOTE: "Rivedi schede in questa nota", CRAM_CARDS_IN_NOTE: "Memorizza schede in questa nota", VIEW_STATS: "Vedi statistiche", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Da rivedere: ${dueNotesCount} scheda/e, ${dueFlashcardsCount} schede in ritardo", SYNC_TIME_TAKEN: "Sincronizzato in ${t}ms", NOTE_IN_IGNORED_FOLDER: "La nota \xE8 salvata in una cartella ignorata (rivedi le impostazioni).", PLEASE_TAG_NOTE: "Per favore etichetta la nota appropriatamente per la revisione (nelle impostazioni).", RESPONSE_RECEIVED: "Risposta ricevuta.", NO_DECK_EXISTS: "Non esistono mazzi per ${deckName}", ALL_CAUGHT_UP: "Sei al passo! :D.", // scheduling.ts DAYS_STR_IVL: "${interval} giorno/i", MONTHS_STR_IVL: "${interval} mese/i", YEARS_STR_IVL: "${interval} anno/i", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}y", // settings.ts SETTINGS_HEADER: "Plugin per ripetizione spaziata", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Per maggiori informazioni, rivolgersi alla wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Cartelle da ignorare", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Schede", FLASHCARD_EASY_LABEL: "Testo del bottone facile", FLASHCARD_GOOD_LABEL: "Testo del bottone buono", FLASHCARD_HARD_LABEL: "Testo del bottone difficile", FLASHCARD_EASY_DESC: 'Personalizza il testo per il pulsante "Facile"', FLASHCARD_GOOD_DESC: 'Personalizza il testo per il pulsante "Buono"', FLASHCARD_HARD_DESC: 'Personalizza il testo per il pulsante "Difficile"', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Etichette delle schede", FLASHCARD_TAGS_DESC: "Inserire etichette separate da spazi o a capi, per esempio #flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "Trasformare cartelle in mazzi e sotto-mazzi?", CONVERT_FOLDERS_TO_DECKS_DESC: "Questa \xE8 un'alternativa all'opzione delle etichette delle schede sopra.", INLINE_SCHEDULING_COMMENTS: "Salvare il commento per l'orario sulla stessa linea dell'ultimna linea della scheda?", INLINE_SCHEDULING_COMMENTS_DESC: "Attivando quest'impostazione far\xF2 s\xEC che i commento HTML non rompino la formattazione delle liste.", BURY_SIBLINGS_TILL_NEXT_DAY: "Sotterrare schede sorelle fino al giorno dopo?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Le schede sorelle sono schede generate dallo stesso testo della scheda, per esempio i.e. cloze deletions", SHOW_CARD_CONTEXT: "Mostrare contesto nelle schede?", SHOW_CARD_CONTEXT_DESC: "per esempio, Titolo > Intestazione 1 > Sottotitolo 1 > ... > Sottotitolo", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Percentuale altezza schede", CARD_MODAL_SIZE_PERCENT_DESC: "Dovrebbe essere 100% se sei su telefono o se hai immagini molto grandi", RESET_DEFAULT: "Reimposta alle impostazioni iniziali", CARD_MODAL_WIDTH_PERCENT: "Percentuale di larghezza delle schede", RANDOMIZE_CARD_ORDER: "Rendere casuale l'ordine delle schede durante la revisione?", REVIEW_CARD_ORDER_WITHIN_DECK: "L'ordine in cui le schede saranno visualizzate all'interno del mazzo", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequenzialmente dentro il mazzo (prima schede nuove)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequenzialmente dentro il mazzo (prima schede in ritardo)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "A caso dentro il mazzo (prima schede nuove)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "A caso dentro il mazzo (prima schede in ritardo)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Scheda a caso da mazzo a caso", REVIEW_DECK_ORDER: "L'ordine in cui i mazzi vengono mostrati durante la revisione", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequenzialmente (quando le schede nel mazzo precedente saranno state riviste)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "A caso (quando le schede nel mazzo precedente saranno state riviste)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Scheda a caso da mazzo a caso", DISABLE_CLOZE_CARDS: "Disabilita schede con spazi da riempire?", CONVERT_HIGHLIGHTS_TO_CLOZES: "Convertire ==testo evidenziato== in spazi da riempire?", CONVERT_BOLD_TEXT_TO_CLOZES: "Convertire **testo in grassetto** in spazi da riempire", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convertire {{parentesi graffe}} in spazi da riempire?", CLOZE_PATTERNS: "Modelli di spazi da riempire", CLOZE_PATTERNS_DESC: 'Inserisci i modelli di spazi da riempire separati da a capo. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Separatore per schede sulla stessa riga", FIX_SEPARATORS_MANUALLY_WARNING: "Si avvisa che dopo aver cambiato questo dovrai manualmente modificare le schede che hai gi\xE0.", INLINE_REVERSED_CARDS_SEPARATOR: "Separatore per schede all'incontrario sulla stessa riga", MULTILINE_CARDS_SEPARATOR: "Separatore per schede su pi\xF9 righe", MULTILINE_REVERSED_CARDS_SEPARATOR: "Separatore per schede all'incontrario su pi\xF9 righe", MULTILINE_CARDS_END_MARKER: "Caratteri che denotano la fine di carte con spazi da riempiere e carte multilinea", NOTES: "Note", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Abilita il pannello di revisione note all'avvio", TAGS_TO_REVIEW: "Etichette da rivedere", TAGS_TO_REVIEW_DESC: "Inserisci le etichette separate da spazi o a capi, tipo #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "Apri una nota a caso per revisione", OPEN_RANDOM_NOTE_DESC: "Quando lo disabiliti, le note saranno ordinate per importanza (PageRank).", AUTO_NEXT_NOTE: "Apri la prossima nota automaticamente dopo la revisione", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Abilita le opzioni di revisione nel menu File (es.: Rivisita: Facile, Buono, Difficile)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Se disabiliti le opzioni di revisione nel menu File, puoi rivedere le tue note utilizzando i comandi del plugin e, se li hai definiti, le scorciatoie da tastiera associate.", MAX_N_DAYS_REVIEW_QUEUE: "Numero di giorni massimi da visualizzare nel pannello di destra", MIN_ONE_DAY: "Il numero di giorni deve essere almeno 1.", VALID_NUMBER_WARNING: "Per favore, mettere un numero valido.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Alberti di mazzi dovrebbero essere inizialmente visualizzate come espansi", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Disabilitami per collassare mazzi annidati nella stessa scheda. Utile se hai schede che appartengono a pi\xF9 mazzi nello stesso file.", ALGORITHM: "Algoritmo", CHECK_ALGORITHM_WIKI: "Per maggiori informazioni, visita l'implementazione dell'algoritmo.", SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Difficolt\xE0 base", BASE_EASE_DESC: "mino = 130, preferibilmente circa 250.", BASE_EASE_MIN_WARNING: "La difficolt\xE0 base deve essere di almeno 130.", LAPSE_INTERVAL_CHANGE: "L'intervallo cambier\xE0 segnando una scheda / nota come difficile", LAPSE_INTERVAL_CHANGE_DESC: "Intervallo nuovo = intervallo vecchio * cambio intervallo / 100.", EASY_BONUS: "Bonus facilit\xE0", EASY_BONUS_DESC: "Il bonus facilit\xE0 ti permette di impostare le differenze negli intervalli tra il rispondere Buono e Facile su una scheda o nota (minimo 100%).", EASY_BONUS_MIN_WARNING: "Il bonus facilit\xE0 deve essere di almeno 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Intervallo massimo in giorni", MAX_INTERVAL_DESC: "Ti permette di mettere un limite massimo all'intervallo (default 100 anni).", MAX_INTERVAL_MIN_WARNING: "L'intervallo massimo deve essere di almeno 1 giorno.", MAX_LINK_CONTRIB: "Contributo massimo delle note collegate", MAX_LINK_CONTRIB_DESC: "Contributo massimo della difficolt\xE0 pasata delle note collegate alla difficolt\xE0 iniziale.", LOGGING: "Registrando", DISPLAY_SCHEDULING_DEBUG_INFO: "Visualizza informazione di debug sulla console per sviluppatori", DISPLAY_PARSER_DEBUG_INFO: "Visualizza informazione di debug riguardanti il parser sulla console per sviluppatori", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Coda di note da rivedere", CLOSE: "Chiusi", NEW: "Nuovo/a", YESTERDAY: "Ieri", TODAY: "Oggi", TOMORROW: "Domani", // stats-modal.tsx STATS_TITLE: "Statistiche", MONTH: "Mese", QUARTER: "Trimestre", YEAR: "Anno", LIFETIME: "Per tutta la vita", FORECAST: "Previsione", FORECAST_DESC: "Il numero di schede che saranno in ritardo in futuro", SCHEDULED: "Programmate", DAYS: "Giorni", NUMBER_OF_CARDS: "Numero di schede", REVIEWS_PER_DAY: "Media: ${avg} revisioni/giorno", INTERVALS: "Intervalli", INTERVALS_DESC: "Ritardi finch\xE9 le revisioni saranno visualizzate di nuovo", COUNT: "Conta", INTERVALS_SUMMARY: "Intervallo medio: ${avg}, Intervallo massimo: ${longest}", EASES: "Difficolt\xE0", EASES_SUMMARY: "Difficolt\xE0 media: ${avgEase}", EASE: "Ease", CARD_TYPES: "Tipi di schede", CARD_TYPES_DESC: "Include eventuali schede sepolte", CARD_TYPE_NEW: "Nuove", CARD_TYPE_YOUNG: "Giovani", CARD_TYPE_MATURE: "Mature", CARD_TYPES_SUMMARY: "Schede tottali: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/ja.ts var ja_default = { // flashcard-modal.tsx DECKS: "\u30C7\u30C3\u30AD", DUE_CARDS: "\u671F\u65E5\u306E\u30AB\u30FC\u30C9", NEW_CARDS: "\u65B0\u898F\u306E\u30AB\u30FC\u30C9", TOTAL_CARDS: "\u30AB\u30FC\u30C9\u5408\u8A08", BACK: "Back", SKIP: "Skip", EDIT_CARD: "Edit Card", RESET_CARD_PROGRESS: "\u30AB\u30FC\u30C9\u306E\u9032\u6357\u3092\u30EA\u30BB\u30C3\u30C8", HARD: "Hard", GOOD: "Good", EASY: "Easy", SHOW_ANSWER: "\u89E3\u7B54\u3092\u8868\u793A", CARD_PROGRESS_RESET: "\u30AB\u30FC\u30C9\u306E\u9032\u6357\u304C\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F\u3002", SAVE: "Save", CANCEL: "Cancel", NO_INPUT: "No input provided.", CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "\u30EC\u30D3\u30E5\u30FC\u3059\u308B\u30CE\u30FC\u30C8\u3092\u958B\u304F", REVIEW_CARDS: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306E\u30EC\u30D3\u30E5\u30FC", REVIEW_DIFFICULTY_FILE_MENU: "\u30EC\u30D3\u30E5\u30FC: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "\u30CE\u30FC\u30C8\u3092${difficulty}\u3068\u3057\u3066\u30EC\u30D3\u30E5\u30FC\u3059\u308B", REVIEW_ALL_CARDS: "\u3059\u3079\u3066\u306E\u30CE\u30FC\u30C8\u304B\u3089\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u3092\u30EC\u30D3\u30E5\u30FC\u3059\u308B", CRAM_ALL_CARDS: "Select a deck to cram", REVIEW_CARDS_IN_NOTE: "\u3053\u306E\u30CE\u30FC\u30C8\u306E\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u3092\u30EC\u30D3\u30E5\u30FC\u3059\u308B", CRAM_CARDS_IN_NOTE: "\u3053\u306E\u30CE\u30FC\u30C8\u306E\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u3092\u8A70\u3081\u8FBC\u307F\u5B66\u7FD2\u3059\u308B", VIEW_STATS: "\u7D71\u8A08\u3092\u95B2\u89A7\u3059\u308B", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "\u30EC\u30D3\u30E5\u30FC: ${dueNotesCount}\u30CE\u30FC\u30C8, ${dueFlashcardsCount}\u30AB\u30FC\u30C9\u304C\u671F\u65E5", SYNC_TIME_TAKEN: "\u540C\u671F\u306B${t}ms\u304B\u304B\u308A\u307E\u3057\u305F\u3002", NOTE_IN_IGNORED_FOLDER: "\u30CE\u30FC\u30C8\u304C\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u306B\u4FDD\u5B58\u3055\u308C\u3066\u3044\u307E\u3059(\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044)\u3002", PLEASE_TAG_NOTE: "\u30EC\u30D3\u30E5\u30FC\u3092\u884C\u3046\u306B\u306F\u30CE\u30FC\u30C8\u306B\u5BFE\u3057\u3066\u6B63\u3057\u304F\u30BF\u30B0\u4ED8\u3051\u3057\u3066\u304F\u3060\u3055\u3044(\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044)\u3002", RESPONSE_RECEIVED: "\u7B54\u3048\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\u3002", NO_DECK_EXISTS: "${deckName}\u306B\u306F\u30C7\u30C3\u30AD\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002", ALL_CAUGHT_UP: "\u4ECA\u65E5\u306E\u8AB2\u984C\u3092\u3059\u3079\u3066\u9054\u6210\u3057\u307E\u3057\u305F :D", // scheduling.ts DAYS_STR_IVL: "${interval}\u65E5\u5F8C", MONTHS_STR_IVL: "${interval}\u6708\u5F8C", YEARS_STR_IVL: "${interval}\u5E74\u5F8C", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}y", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '\u8A73\u7D30\u306B\u3064\u3044\u3066\u306Fwiki\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9", FLASHCARD_EASY_LABEL: "Easy Button Text", FLASHCARD_GOOD_LABEL: "Good Button Text", FLASHCARD_HARD_LABEL: "Hard Button Text", FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button', FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button', FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306B\u4F7F\u7528\u3059\u308B\u30BF\u30B0", FLASHCARD_TAGS_DESC: '\u30BF\u30B0\u3092\u30B9\u30DA\u30FC\u30B9\u307E\u305F\u306F\u6539\u884C\u3067\u533A\u5207\u3063\u3066\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u4F8B: "#flashcards #deck2 #deck3"', CONVERT_FOLDERS_TO_DECKS: "\u30D5\u30A9\u30EB\u30C0\u3092\u30C7\u30C3\u30AD\u3068\u30B5\u30D6\u30C7\u30C3\u30AD\u3068\u3057\u3066\u4F7F\u7528\u3057\u307E\u3059\u304B\uFF1F", CONVERT_FOLDERS_TO_DECKS_DESC: "\u3053\u308C\u306F\u4E0A\u8A18\u306E\u30BF\u30B0\u3092\u4F7F\u7528\u3057\u305F\u30C7\u30C3\u30AD\u69CB\u7BC9\u306E\u4EE3\u66FF\u3068\u306A\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3059\u3002", INLINE_SCHEDULING_COMMENTS: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306E\u6700\u7D42\u884C\u3068\u540C\u4E00\u306E\u884C\u306B\u30B9\u30B1\u30B8\u30E5\u30FC\u30EA\u30F3\u30B0\u30B3\u30E1\u30F3\u30C8\u3092\u4FDD\u5B58\u3057\u307E\u3059\u304B\uFF1F", INLINE_SCHEDULING_COMMENTS_DESC: "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u5316\u3059\u308B\u3068\u3001HTML\u30B3\u30E1\u30F3\u30C8\u306B\u3088\u3063\u3066Markdown\u306E\u30EA\u30B9\u30C8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u5D29\u308C\u306A\u304F\u306A\u308A\u307E\u3059\u3002", BURY_SIBLINGS_TILL_NEXT_DAY: "\u6B21\u306E\u30EC\u30D3\u30E5\u30FC\u307E\u3067\u30B7\u30D6\u30EA\u30F3\u30B0\u3092\u5EF6\u671F\u3057\u307E\u3059\u304B\uFF1F", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "\u30B7\u30D6\u30EA\u30F3\u30B0\u306F\u540C\u4E00\u306E\u30AB\u30FC\u30C9\u30C6\u30AD\u30B9\u30C8\u304B\u3089\u751F\u6210\u3055\u308C\u305F\u30AB\u30FC\u30C9\u3001\u3064\u307E\u308A\u7A74\u57CB\u3081\u554F\u984C\u306E\u6D3E\u751F\u30AB\u30FC\u30C9\u3067\u3059\u3002", SHOW_CARD_CONTEXT: "\u30AB\u30FC\u30C9\u306B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\u304B\uFF1F", SHOW_CARD_CONTEXT_DESC: "\uFF62\u30BF\u30A4\u30C8\u30EB > \u898B\u51FA\u3057 1 > \u526F\u898B\u51FA\u3057 > ... > \u526F\u898B\u51FA\u3057\uFF63\u306E\u8868\u793A\u3092\u884C\u3046\u304B\u3069\u3046\u304B\u3092\u6C7A\u3081\u307E\u3059\u3002", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306E\u7E26\u30B5\u30A4\u30BA\u306E\u30D1\u30FC\u30BB\u30F3\u30C6\u30FC\u30B8", CARD_MODAL_SIZE_PERCENT_DESC: "\u30E2\u30D0\u30A4\u30EB\u7248\u3001\u307E\u305F\u306F\u975E\u5E38\u306B\u5927\u304D\u306A\u30B5\u30A4\u30BA\u306E\u753B\u50CF\u304C\u3042\u308B\u5834\u5408\u306B\u306F100%\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002", RESET_DEFAULT: "\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306B\u30EA\u30BB\u30C3\u30C8\u3059\u308B", CARD_MODAL_WIDTH_PERCENT: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306E\u6A2A\u30B5\u30A4\u30BA\u306E\u30D1\u30FC\u30BB\u30F3\u30C6\u30FC\u30B8", RANDOMIZE_CARD_ORDER: "\u30EC\u30D3\u30E5\u30FC\u4E2D\u306E\u30AB\u30FC\u30C9\u306E\u9806\u756A\u3092\u30E9\u30F3\u30C0\u30E0\u306B\u3057\u307E\u3059\u304B\uFF1F", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "\u7A74\u57CB\u3081\u30AB\u30FC\u30C9\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u304B\uFF1F", CONVERT_HIGHLIGHTS_TO_CLOZES: "==\u30CF\u30A4\u30E9\u30A4\u30C8==\u3092\u7A74\u57CB\u3081\u3068\u3057\u3066\u4F7F\u7528\u3057\u307E\u3059\u304B\uFF1F", CONVERT_BOLD_TEXT_TO_CLOZES: "**\u30DC\u30FC\u30EB\u30C9\u4F53**\u3092\u7A74\u57CB\u3081\u3068\u3057\u3066\u4F7F\u7528\u3057\u307E\u3059\u304B\uFF1F", CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{\u4E2D\u62EC\u5F27}}\u3092\u7A74\u57CB\u3081\u3068\u3057\u3066\u4F7F\u7528\u3057\u307E\u3059\u304B\uFF1F", CLOZE_PATTERNS: "\u7A74\u57CB\u3081\u30D1\u30BF\u30FC\u30F3", CLOZE_PATTERNS_DESC: '\u6539\u884C\u3067\u533A\u5207\u3063\u3066\u7A74\u57CB\u3081\u30D1\u30BF\u30FC\u30F3\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002 Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\u30A4\u30F3\u30E9\u30A4\u30F3\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306B\u4F7F\u7528\u3059\u308B\u30BB\u30D1\u30EC\u30FC\u30BF\u30FC", FIX_SEPARATORS_MANUALLY_WARNING: "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u5909\u66F4\u3059\u308B\u5834\u5408\u306B\u306F\u3001\u4F5C\u6210\u6E08\u307F\u306E\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u3092\u624B\u52D5\u3067\u7DE8\u96C6\u3057\u76F4\u3059\u5FC5\u8981\u304C\u3042\u308B\u3053\u3068\u306B\u6CE8\u610F\u3057\u3066\u304F\u3060\u3055\u3044\u3002", INLINE_REVERSED_CARDS_SEPARATOR: "\u30A4\u30F3\u30E9\u30A4\u30F3\u306E\u8868\u88CF\u53CD\u8EE2\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306B\u4F7F\u7528\u3059\u308B\u30BB\u30D1\u30EC\u30FC\u30BF\u30FC", MULTILINE_CARDS_SEPARATOR: "\u8907\u6570\u884C\u306E\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306B\u4F7F\u7528\u3059\u308B\u30BB\u30D1\u30EC\u30FC\u30BF\u30FC", MULTILINE_REVERSED_CARDS_SEPARATOR: "\u8907\u6570\u884C\u306E\u8868\u88CF\u53CD\u8EE2\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306B\u4F7F\u7528\u3059\u308B\u30BB\u30D1\u30EC\u30FC\u30BF\u30FC", MULTILINE_CARDS_END_MARKER: "\u30AF\u30ED\u30FC\u30BA\u3068\u8907\u6570\u884C\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9\u306E\u7D42\u308F\u308A\u3092\u793A\u3059\u6587\u5B57", NOTES: "\u30CE\u30FC\u30C8", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Enable note review pane on startup", TAGS_TO_REVIEW: "\u30EC\u30D3\u30E5\u30FC\u306B\u4F7F\u7528\u3059\u308B\u30BF\u30B0", TAGS_TO_REVIEW_DESC: '\u30BF\u30B0\u3092\u30B9\u30DA\u30FC\u30B9\u307E\u305F\u306F\u6539\u884C\u3067\u533A\u5207\u3063\u3066\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u4F8B: "#review #tag2 #tag3"', OPEN_RANDOM_NOTE: "\u30E9\u30F3\u30C0\u30E0\u306B\u30CE\u30FC\u30C8\u3092\u958B\u3044\u3066\u30EC\u30D3\u30E5\u30FC\u3059\u308B", OPEN_RANDOM_NOTE_DESC: "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u7121\u52B9\u5316\u3055\u308C\u3066\u3044\u308B\u72B6\u614B\u3067\u306F\u3001\u30CE\u30FC\u30C8\u306F\u91CD\u8981\u5EA6(\u30DA\u30FC\u30B8\u30E9\u30F3\u30AF)\u306B\u3088\u308B\u9806\u756A\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002", AUTO_NEXT_NOTE: "\u30EC\u30D3\u30E5\u30FC\u5F8C\u306B\u6B21\u306E\u30CE\u30FC\u30C8\u3092\u81EA\u52D5\u7684\u306B\u958B\u304F", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\u30D5\u30A1\u30A4\u30EB\u30E1\u30CB\u30E5\u30FC\u3067\u30EC\u30D3\u30E5\u30FC\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: Easy, Good, Hard\uFF09", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\u30D5\u30A1\u30A4\u30EB\u30E1\u30CB\u30E5\u30FC\u3067\u30EC\u30D3\u30E5\u30FC\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3057\u305F\u5834\u5408\u3001\u30D7\u30E9\u30B0\u30A4\u30F3\u30B3\u30DE\u30F3\u30C9\u3084\u3001\u8A2D\u5B9A\u3057\u3066\u3044\u308B\u5834\u5408\u306F\u5BFE\u5FDC\u3059\u308B\u30DB\u30C3\u30C8\u30AD\u30FC\u3092\u4F7F\u7528\u3057\u3066\u30E1\u30E2\u3092\u30EC\u30D3\u30E5\u30FC\u3067\u304D\u307E\u3059\u3002", MAX_N_DAYS_REVIEW_QUEUE: "\u53F3\u30D1\u30CD\u30EB\u306B\u8868\u793A\u3059\u308B\u6700\u5927\u306E\u65E5\u6570", MIN_ONE_DAY: "\u65E5\u6570\u306B\u306F1\u4EE5\u4E0A\u306E\u6570\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002", VALID_NUMBER_WARNING: "\u6709\u52B9\u306A\u6570\u5B57\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\u30C7\u30C3\u30AD \u30C4\u30EA\u30FC\u306F\u6700\u521D\u306F\u5C55\u958B\u3057\u3066\u8868\u793A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "\u3053\u308C\u3092\u30AA\u30D5\u306B\u3059\u308B\u3068\u3001\u540C\u3058\u30AB\u30FC\u30C9\u5185\u306E\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30C7\u30C3\u30AD\u304C\u6298\u308A\u305F\u305F\u307E\u308C\u307E\u3059\u3002\u540C\u3058\u30D5\u30A1\u30A4\u30EB\u306B\u591A\u304F\u306E\u30C7\u30C3\u30AD\u306B\u5C5E\u3059\u308B\u30AB\u30FC\u30C9\u304C\u3042\u308B\u5834\u5408\u306B\u4FBF\u5229\u3067\u3059\u3002", ALGORITHM: "\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0", CHECK_ALGORITHM_WIKI: '\u8A73\u7D30\u306B\u3064\u3044\u3066\u306F\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u5B9F\u88C5\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\u30D9\u30FC\u30B9\u306E\u6613\u3057\u3055", BASE_EASE_DESC: "\u6700\u5C0F\u5024\u306F130\u3067\u3059\u304C\u3001 \u9069\u6B63\u5024\u306F\u304A\u304A\u3088\u305D250\u3067\u3059\u3002", BASE_EASE_MIN_WARNING: "\u30D9\u30FC\u30B9\u306E\u6613\u3057\u3055\u306B\u306F130\u4EE5\u4E0A\u306E\u6570\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002", LAPSE_INTERVAL_CHANGE: "\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9/\u30CE\u30FC\u30C8\u3092Hard\u3068\u3057\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u305F\u969B\u306E\u9593\u9694\u5909\u66F4", LAPSE_INTERVAL_CHANGE_DESC: '"\u65B0\u3057\u3044\u9593\u9694 = \u4EE5\u524D\u306E\u9593\u9694 * \u9593\u9694\u5909\u66F4 / 100" \u3068\u3057\u3066\u8A08\u7B97\u3055\u308C\u307E\u3059\u3002', EASY_BONUS: "Easy\u30DC\u30FC\u30CA\u30B9", EASY_BONUS_DESC: "Easy\u30DC\u30FC\u30CA\u30B9\u306B\u3088\u3063\u3066\u30D5\u30E9\u30C3\u30B7\u30E5\u30AB\u30FC\u30C9/\u30CE\u30FC\u30C8\u306B\u304A\u3051\u308B\u9593\u9694\u306E\u5DEE\u5206\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u3059(\u6700\u5C0F\u5024 = 100%)\u3002", EASY_BONUS_MIN_WARNING: "Easy\u30DC\u30FC\u30CA\u30B9\u306B\u306F100\u4EE5\u4E0A\u306E\u6570\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximum interval in days", MAX_INTERVAL_DESC: "\u9593\u9694\u306B\u4E0A\u9650\u5024\u3092\u8A2D\u5B9A\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8\u5024 = 100\u5E74)\u3002", MAX_INTERVAL_MIN_WARNING: "\u9593\u9694\u306E\u6700\u5927\u5024\u306B\u306F1\u4EE5\u4E0A\u306E\u6570\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002", MAX_LINK_CONTRIB: "\u30EA\u30F3\u30AF\u30B3\u30F3\u30C8\u30EA\u30D3\u30E5\u30FC\u30B7\u30E7\u30F3\u306E\u6700\u5927\u5024", MAX_LINK_CONTRIB_DESC: "\u6700\u521D\u306E\u6613\u3057\u3055\u306B\u5BFE\u3057\u3066\u3001\u30EA\u30F3\u30AF\u3055\u308C\u305F\u30CE\u30FC\u30C8\u306E\u91CD\u307F\u4ED8\u3051\u3055\u308C\u305F\u6613\u3057\u3055\u304C\u5BC4\u4E0E\u3059\u308B\u6700\u5927\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002", LOGGING: "\u30ED\u30B0\u7BA1\u7406", DISPLAY_SCHEDULING_DEBUG_INFO: "\u30C7\u30D9\u30ED\u30C3\u30D1\u30FC\u30B3\u30F3\u30BD\u30FC\u30EB\u306B\u3066\u30C7\u30D0\u30C3\u30B0\u60C5\u5831\u3092\u8868\u793A\u3057\u307E\u3059\u304B", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\u30CE\u30FC\u30C8\u30EC\u30D3\u30E5\u30FC\u306E\u30AD\u30E5\u30FC", CLOSE: "\u9589\u3058\u308B", NEW: "\u65B0\u898F", YESTERDAY: "\u6628\u65E5", TODAY: "\u4ECA\u65E5", TOMORROW: "\u660E\u65E5", // stats-modal.tsx STATS_TITLE: "\u7D71\u8A08", MONTH: "Month", QUARTER: "Quarter", YEAR: "Year", LIFETIME: "Lifetime", FORECAST: "\u4E88\u6E2C", FORECAST_DESC: "\u5FA9\u7FD2\u671F\u65E5\u304C\u6765\u308B\u30AB\u30FC\u30C9\u306E\u679A\u6570", SCHEDULED: "\u30B9\u30B1\u30B8\u30E5\u30FC\u30EA\u30F3\u30B0\u6E08\u307F", DAYS: "\u65E5", NUMBER_OF_CARDS: "\u30AB\u30FC\u30C9\u6570", REVIEWS_PER_DAY: "\u5E73\u5747: ${avg}\u30EC\u30D3\u30E5\u30FC/\u65E5", INTERVALS: "\u9593\u9694", INTERVALS_DESC: "\u6B21\u306E\u30EC\u30D3\u30E5\u30FC\u4E88\u5B9A\u65E5", COUNT: "\u30AB\u30A6\u30F3\u30C8", INTERVALS_SUMMARY: "\u9593\u9694\u306E\u5E73\u5747\u5024: ${avg}, \u6700\u9577\u306E\u9593\u9694: ${longest}", EASES: "\u6613\u3057\u3055", EASES_SUMMARY: "\u6613\u3057\u3055\u306E\u5E73\u5747\u5024: ${avgEase}", EASE: "Ease", CARD_TYPES: "\u30AB\u30FC\u30C9\u30BF\u30A4\u30D7", CARD_TYPES_DESC: "\u5EF6\u671F\u306E\u30AB\u30FC\u30C9\u304C\u3042\u308B\u5834\u5408\u306B\u306F\u3053\u308C\u306B\u542B\u307E\u308C\u307E\u3059", CARD_TYPE_NEW: "\u65B0\u898F", CARD_TYPE_YOUNG: "\u5FA9\u7FD2(\u521D\u671F)", CARD_TYPE_MATURE: "\u5FA9\u7FD2(\u5F8C\u671F)", CARD_TYPES_SUMMARY: "\u30AB\u30FC\u30C9\u306E\u5408\u8A08: ${totalCardsCount}\u679A", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/ko.ts var ko_default = { // flashcard-modal.tsx DECKS: "\uB371", DUE_CARDS: "\uB2E4\uC2DC \uBCFC \uCE74\uB4DC\uB4E4", NEW_CARDS: "\uC0C8\uB85C\uC6B4 \uCE74\uB4DC\uB4E4", TOTAL_CARDS: "\uC804\uCCB4 \uCE74\uB4DC\uB4E4", BACK: "Back", SKIP: "Skip", EDIT_CARD: "Edit Card", RESET_CARD_PROGRESS: "\uCE74\uB4DC\uC758 \uC9C4\uD589\uC0C1\uD669\uC744 \uCD08\uAE30\uD654\uD569\uB2C8\uB2E4.", HARD: "\uC5B4\uB824\uC6C0(Hard)", GOOD: "\uC88B\uC74C(Good)", EASY: "\uC26C\uC6C0(Easy)", SHOW_ANSWER: "\uC815\uB2F5 \uD655\uC778\uD558\uAE30", CARD_PROGRESS_RESET: "\uCE74\uB4DC\uC758 \uC9C4\uD589\uC0C1\uD669\uC774 \uCD08\uAE30\uD654\uB418\uC5C8\uC2B5\uB2C8\uB2E4.", SAVE: "Save", CANCEL: "Cancel", NO_INPUT: "No input provided.", CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "\uB9AC\uBDF0\uD560 \uB178\uD2B8 \uC5F4\uAE30", REVIEW_CARDS: "\uD50C\uB798\uC2DC\uCE74\uB4DC \uB9AC\uBDF0", REVIEW_DIFFICULTY_FILE_MENU: "\uB9AC\uBDF0: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "\uB178\uD2B8\uB97C ${difficulty}\uC73C\uB85C \uB9AC\uBDF0\uD569\uB2C8\uB2E4", REVIEW_ALL_CARDS: "\uBAA8\uB4E0 \uB178\uD2B8\uB4E4\uC758 \uD50C\uB798\uC2DC\uCE74\uB4DC\uB4E4\uC744 \uB9AC\uBDF0\uD569\uB2C8\uB2E4", CRAM_ALL_CARDS: "Select a deck to cram", REVIEW_CARDS_IN_NOTE: "\uC774 \uB178\uD2B8\uC758 \uD50C\uB798\uC2DC\uCE74\uB4DC\uB4E4\uC744 \uB9AC\uBDF0\uD569\uB2C8\uB2E4", CRAM_CARDS_IN_NOTE: "\uC774 \uB178\uD2B8\uC758 \uD50C\uB798\uC2DC\uCE74\uB4DC\uB4E4\uC744 \uBCBC\uB77D\uCE58\uAE30\uD569\uB2C8\uB2E4.", VIEW_STATS: "\uD1B5\uACC4 \uD655\uC778", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "--\uB9AC\uBDF0: ${dueNotesCount} \uB178\uD2B8, ${dueFlashcardsCount} \uCE74\uB4DC \uB0A8\uC558\uC2B5\uB2C8\uB2E4.", SYNC_TIME_TAKEN: "\uB3D9\uAE30\uD654\uC5D0 ${t}\uBC00\uB9AC\uCD08 \uAC78\uB838\uC2B5\uB2C8\uB2E4", NOTE_IN_IGNORED_FOLDER: "\uB178\uD2B8\uAC00 \uBB34\uC2DC\uB41C \uD3F4\uB354 \uC544\uB798\uC5D0 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. (\uC124\uC815\uC744 \uD655\uC778\uD574\uC8FC\uC138\uC694)", PLEASE_TAG_NOTE: "\uB9AC\uBDF0\uB97C \uD558\uAE30\uC704\uD574 \uB178\uD2B8\uC5D0 \uC801\uC808\uD788 \uD0DC\uADF8\uD574\uC8FC\uC138\uC694. (\uC124\uC815\uC744 \uD655\uC778\uD574\uC8FC\uC138\uC694)", RESPONSE_RECEIVED: "\uC694\uCCAD\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4", NO_DECK_EXISTS: "${deckName}\uC774\uB77C\uB294 \uC774\uB984\uC758 \uB371\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", ALL_CAUGHT_UP: "\uBAA8\uB450 \uD655\uC778\uD588\uC2B5\uB2C8\uB2E4. :D", // scheduling.ts DAYS_STR_IVL: "${interval} \uC77C \uD6C4", MONTHS_STR_IVL: "${interval} \uAC1C\uC6D4 \uD6C4", YEARS_STR_IVL: "${interval} \uB144 \uD6C4", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}y", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '\uB354 \uB9CE\uC740 \uC815\uBCF4\uB97C \uC6D0\uD558\uC2DC\uBA74, wiki\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\uBB34\uC2DC\uD560 \uD3F4\uB354\uB4E4", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\uD50C\uB798\uC2DC\uCE74\uB4DC", FLASHCARD_EASY_LABEL: "Easy Button Text", FLASHCARD_GOOD_LABEL: "Good Button Text", FLASHCARD_HARD_LABEL: "Hard Button Text", FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button', FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button', FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\uD50C\uB798\uC2DC\uCE74\uB4DC \uD0DC\uADF8", FLASHCARD_TAGS_DESC: "\uD0DC\uADF8\uB97C \uACF5\uBC31 \uB610\uB294 \uBE48 \uC904\uB85C \uAD6C\uBD84\uD574\uC11C \uC785\uB825\uD574\uC8FC\uC138\uC694. \uC608) '#flashcards #deck2 #deck3'", CONVERT_FOLDERS_TO_DECKS: "\uD3F4\uB354\uB97C \uB371\uACFC \uC11C\uBE0C\uB371\uC73C\uB85C \uC0AC\uC6A9\uD560\uAE4C\uC694?", CONVERT_FOLDERS_TO_DECKS_DESC: "\uC774 \uAE30\uB2A5\uC740 \uC704\uC758 \uD50C\uB798\uC2DC\uCE74\uB4DC \uD0DC\uADF8 \uC635\uC158\uC744 \uB300\uCCB4\uD569\uB2C8\uB2E4.", INLINE_SCHEDULING_COMMENTS: "\uD50C\uB798\uC2DC\uCE74\uB4DC\uC758 \uB9C8\uC9C0\uB9C9 \uC904\uACFC \uB3D9\uC77C\uD55C \uC904\uC5D0 \uC2A4\uCF00\uC904\uB9C1 \uCF54\uBA58\uD2B8\uB97C \uC800\uC7A5\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", INLINE_SCHEDULING_COMMENTS_DESC: "\uC774 \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 HTML \uC8FC\uC11D\uC774 \uBAA9\uB85D\uC758 \uD3EC\uB9E4\uD305\uC744 \uBB34\uB108\uD2B8\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", BURY_SIBLINGS_TILL_NEXT_DAY: "Sibling \uCE74\uB4DC\uB97C \uB2E4\uC74C\uB0A0\uAE4C\uC9C0 \uBB3B\uC5B4\uB450\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Sibling \uCE74\uB4DC\uB294 \uB3D9\uC77C\uD55C \uCE74\uB4DC \uD14D\uC2A4\uD2B8\uC5D0\uC11C \uC0DD\uC131\uB41C \uCE74\uB4DC\uC785\uB2C8\uB2E4. i.e. cloze deletions", SHOW_CARD_CONTEXT: "\uCE74\uB4DC\uC758 \uBB38\uB9E5(context)\uC744 \uD45C\uC2DC\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", SHOW_CARD_CONTEXT_DESC: "\uCE74\uB4DC\uC5D0\uC11C 'Title > Heading 1 > Subheading > ... > Subheading' \uC758 \uD45C\uC2DC\uB97C \uD560\uC9C0 \uC124\uC815\uD569\uB2C8\uB2E4.", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\uD50C\uB798\uC2DC\uCE74\uB4DC \uB192\uC774 \uBE44\uC728", CARD_MODAL_SIZE_PERCENT_DESC: "\uBAA8\uBC14\uC77C \uBC84\uC804 \uD639\uC740 \uB9E4\uC6B0 \uD070 \uC774\uBBF8\uC9C0\uAC00 \uC788\uB294 \uACBD\uC6B0 100%\uB85C \uC124\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.", RESET_DEFAULT: "\uAE30\uBCF8\uAC12\uC73C\uB85C \uCD08\uAE30\uD654", CARD_MODAL_WIDTH_PERCENT: "\uD50C\uB798\uC2DC\uCE74\uB4DC \uB108\uBE44 \uBE44\uC728", RANDOMIZE_CARD_ORDER: "\uB9AC\uBDF0\uC911\uC778 \uCE74\uB4DC\uC758 \uC21C\uC11C\uB97C \uB79C\uB364\uC73C\uB85C \uB450\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "\uBE48 \uCE78 \uCC44\uC6B0\uAE30 \uCE74\uB4DC\uB97C \uBE44\uD65C\uC131\uD654\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", CONVERT_HIGHLIGHTS_TO_CLOZES: "==highlights== \uB97C \uBE48 \uCE78 \uCC44\uC6B0\uAE30\uB85C \uC804\uD658\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", CONVERT_BOLD_TEXT_TO_CLOZES: "**bolded text** \uB97C \uBE48 \uCE78 \uCC44\uC6B0\uAE30\uB85C \uC804\uD658\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{curly brackets}} \uB97C \uBE48 \uCE78 \uCC44\uC6B0\uAE30\uB85C \uC804\uD658\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?", CLOZE_PATTERNS: "\uBE48 \uCE78 \uCC44\uC6B0\uAE30 \uD328\uD134", CLOZE_PATTERNS_DESC: '\uBE48 \uCE78 \uCC44\uC6B0\uAE30 \uD328\uD134\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694. \uC904\uBC14\uAFC8\uC73C\uB85C \uAD6C\uBD84\uD569\uB2C8\uB2E4. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\uC778\uB77C\uC778 \uD50C\uB798\uC2DC\uCE74\uB4DC \uAD6C\uBD84\uC790", FIX_SEPARATORS_MANUALLY_WARNING: "\uC8FC\uC758: \uC774 \uC635\uC158\uC744 \uC218\uC815\uD55C \uD6C4\uC5D0\uB294 \uC774\uBBF8 \uC791\uC131\uB41C \uD50C\uB798\uC2DC\uCE74\uB4DC\uB97C \uC218\uB3D9\uC73C\uB85C \uC218\uC815\uD574\uC57C \uD568\uC744 \uC8FC\uC758\uD558\uC2ED\uC2DC\uC624.", INLINE_REVERSED_CARDS_SEPARATOR: "\uC778\uB77C\uC778 \uBC18\uC804 \uD50C\uB798\uC2DC\uCE74\uB4DC \uAD6C\uBD84\uC790", MULTILINE_CARDS_SEPARATOR: "\uC5EC\uB7EC \uC904 \uD50C\uB798\uC2DC\uCE74\uB4DC \uAD6C\uBD84\uC790", MULTILINE_REVERSED_CARDS_SEPARATOR: "\uC5EC\uB7EC \uC904 \uBC18\uC804 \uD50C\uB798\uC2DC\uCE74\uB4DC \uAD6C\uBD84\uC790", MULTILINE_CARDS_END_MARKER: "\uD074\uB85C\uC988\uC640 \uB2E4\uC911 \uD589 \uD50C\uB798\uC2DC\uCE74\uB4DC\uC758 \uB05D\uC744 \uB098\uD0C0\uB0B4\uB294 \uBB38\uC790", NOTES: "\uB178\uD2B8", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Enable note review pane on startup", TAGS_TO_REVIEW: "\uB9AC\uBDF0\uC5D0 \uC0AC\uC6A9\uD560 \uD0DC\uADF8", TAGS_TO_REVIEW_DESC: "\uD0DC\uADF8\uB97C \uACF5\uBC31 \uB610\uB294 \uBE48 \uC904\uB85C \uAD6C\uBD84\uD574\uC11C \uC785\uB825\uD574\uC8FC\uC138\uC694. \uC608) '#review #tag2 #tag3'", OPEN_RANDOM_NOTE: "\uB9AC\uBDF0\uB97C \uC704\uD574 \uB79C\uB364 \uB178\uD2B8\uB97C \uC5FD\uB2C8\uB2E4.", OPEN_RANDOM_NOTE_DESC: "\uC774 \uC635\uC158\uC774 \uAEBC\uC838\uC788\uC73C\uBA74, \uB178\uD2B8\uB294 \uC911\uC694\uB3C4(\uD398\uC774\uC9C0 \uB7AD\uD06C)\uC5D0 \uB530\uB77C \uC815\uB82C\uB429\uB2C8\uB2E4.", AUTO_NEXT_NOTE: "\uB9AC\uBDF0 \uD6C4\uC5D0 \uB2E4\uC74C \uB178\uD2B8\uB97C \uC790\uB3D9\uC73C\uB85C \uC5FD\uB2C8\uB2E4.", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\uD30C\uC77C \uBA54\uB274\uC5D0\uC11C \uAC80\uD1A0 \uC635\uC158\uC744 \uD65C\uC131\uD654\uD558\uC138\uC694 (\uC608: \uAC80\uD1A0: \uC26C\uC6C0, \uC88B\uC74C, \uC5B4\uB824\uC6C0)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\uD30C\uC77C \uBA54\uB274\uC5D0\uC11C \uAC80\uD1A0 \uC635\uC158\uC744 \uBE44\uD65C\uC131\uD654\uD558\uBA74 \uD50C\uB7EC\uADF8\uC778 \uBA85\uB839\uC744 \uC0AC\uC6A9\uD574 \uB178\uD2B8\uB97C \uAC80\uD1A0\uD560 \uC218 \uC788\uC73C\uBA70, \uC815\uC758\uB41C \uACBD\uC6B0\uC5D0\uB294 \uAD00\uB828\uB41C \uB2E8\uCD95\uD0A4\uB3C4 \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", MAX_N_DAYS_REVIEW_QUEUE: "\uC624\uB978\uCABD \uD328\uB110\uC5D0 \uD45C\uC2DC\uD560 \uCD5C\uB300 \uC77C\uC218", MIN_ONE_DAY: "\uC801\uC5B4\uB3C4 1\uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.", VALID_NUMBER_WARNING: "\uC720\uD6A8\uD55C \uC22B\uC790\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\uB371 \uD2B8\uB9AC\uB294 \uCC98\uC74C\uC5D0 \uD655\uC7A5\uB41C \uAC83\uC73C\uB85C \uD45C\uC2DC\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "\uAC19\uC740 \uCE74\uB4DC\uC5D0 \uC911\uCCA9\uB41C \uB371\uC744 \uC811\uC73C\uB824\uBA74 \uC774 \uC635\uC158\uC744 \uB044\uC2ED\uC2DC\uC624. \uAC19\uC740 \uD30C\uC77C\uC5D0 \uC5EC\uB7EC \uB371\uC5D0 \uC18D\uD55C \uCE74\uB4DC\uAC00 \uC788\uB294 \uACBD\uC6B0 \uC720\uC6A9\uD569\uB2C8\uB2E4.", ALGORITHM: "\uC54C\uACE0\uB9AC\uC998", CHECK_ALGORITHM_WIKI: '\uB354 \uB9CE\uC740 \uC815\uBCF4\uB97C \uC6D0\uD558\uC2DC\uBA74, algorithm details\uC744 \uD655\uC778\uD574\uC8FC\uC138\uC694.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\uAE30\uBCF8 ease", BASE_EASE_DESC: "\uCD5C\uC19F\uAC12 = 130, \uC801\uC815\uCE58\uB294 \uB300\uB7B5 250\uC785\uB2C8\uB2E4.", BASE_EASE_MIN_WARNING: "\uAE30\uBCF8 ease\uB294 \uC801\uC5B4\uB3C4 130 \uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.", LAPSE_INTERVAL_CHANGE: "\uD50C\uB798\uC2DC\uCE74\uB4DC/\uB178\uD2B8\uB97C \uC5B4\uB824\uC6C0(Hard)\uC73C\uB85C \uB9AC\uBDF0\uD588\uC744 \uB54C\uC758 \uAC04\uACA9 \uBCC0\uACBD", LAPSE_INTERVAL_CHANGE_DESC: "\uC0C8\uB85C\uC6B4 \uAC04\uACA9 = \uC774\uC804 \uAC04\uACA9 * \uAC04\uACA9\uBCC0\uACBD \uAC12 / 100.", EASY_BONUS: "\uC26C\uC6C0(Easy) \uBCF4\uB108\uC2A4", EASY_BONUS_DESC: "\uC26C\uC6C0(Easy) \uBCF4\uB108\uC2A4\uB294 \uD50C\uB798\uC2DC\uCE74\uB4DC/\uB178\uD2B8\uC5D0\uC11C \uC88B\uC74C(Good)\uACFC \uC26C\uC6C0(Easy) \uC0AC\uC774\uC758 \uAC04\uACA9 \uCC28\uC774\uB97C \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. (\uCD5C\uC18C = 100%)", EASY_BONUS_MIN_WARNING: "\uC26C\uC6C0(Easy) \uBCF4\uB108\uC2A4\uB294 \uC801\uC5B4\uB3C4 100\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maximum interval in days", MAX_INTERVAL_DESC: "\uAC04\uACA9\uC758 \uC0C1\uD55C\uC120\uC744 \uB458 \uC218 \uC788\uC2B5\uB2C8\uB2E4. (\uAE30\uBCF8\uAC12 = 100\uB144)", MAX_INTERVAL_MIN_WARNING: "\uCD5C\uB300 \uAC04\uACA9\uC740 \uC801\uC5B4\uB3C4 1\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.", MAX_LINK_CONTRIB: "\uCD5C\uB300 \uC5F0\uACB0 \uAE30\uC5EC\uB3C4", MAX_LINK_CONTRIB_DESC: "\uB9C1\uD06C\uB41C \uB178\uD2B8\uC758 \uCD08\uAE30 ease\uC5D0 \uB300\uD55C \uAC00\uC911\uCE58\uAC00 \uC801\uC6A9\uB41C ease\uC758 \uCD5C\uB300 \uAE30\uC5EC\uB3C4\uC785\uB2C8\uB2E4.", LOGGING: "\uB85C\uAE45", DISPLAY_SCHEDULING_DEBUG_INFO: "\uB514\uBC84\uAE45 \uC815\uBCF4\uB97C \uAC1C\uBC1C\uC790 \uCF58\uC194\uC5D0 \uD45C\uC2DC\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\uB9AC\uBDF0\uD560 \uB178\uD2B8 \uB300\uAE30\uC5F4", CLOSE: "\uB2EB\uAE30", NEW: "New", YESTERDAY: "\uC5B4\uC81C", TODAY: "\uC624\uB298", TOMORROW: "\uB0B4\uC77C", // stats-modal.tsx STATS_TITLE: "\uD1B5\uACC4", MONTH: "\uC6D4", QUARTER: "\uBD84\uAE30", YEAR: "\uB144", LIFETIME: "\uD3C9\uC0DD", FORECAST: "\uC608\uCE21", FORECAST_DESC: "\uC774\uD6C4\uC5D0 \uD559\uC2B5\uD560 \uCE74\uB4DC\uC758 \uC218", SCHEDULED: "Scheduled", DAYS: "\uC77C", NUMBER_OF_CARDS: "\uCE74\uB4DC\uC758 \uC218", REVIEWS_PER_DAY: "\uD3C9\uADE0: ${avg} \uB9AC\uBDF0/\uC77C", INTERVALS: "\uAC04\uACA9", INTERVALS_DESC: "\uB9AC\uBDF0\uB97C \uB2E4\uC2DC \uD560 \uB54C \uAE4C\uC9C0\uC758 \uAE30\uAC04", COUNT: "Count", INTERVALS_SUMMARY: "\uD3C9\uADE0 \uAC04\uACA9: ${avg}, \uAC00\uC7A5 \uAE34 \uAC04\uACA9: ${longest}", EASES: "Eases", EASES_SUMMARY: "Average ease: ${avgEase}", EASE: "Ease", CARD_TYPES: "\uCE74\uB4DC \uD0C0\uC785", CARD_TYPES_DESC: "\uC5EC\uAE30\uC5D0\uB294 \uBB3B\uC5B4\uB454 \uCE74\uB4DC\uB3C4 \uD3EC\uD568\uB429\uB2C8\uB2E4.", CARD_TYPE_NEW: "New", CARD_TYPE_YOUNG: "Young", CARD_TYPE_MATURE: "Mature", CARD_TYPES_SUMMARY: "\uC804\uCCB4 \uCE74\uB4DC \uC218: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/mr.ts var mr_default = {}; // src/lang/locale/nl.ts var nl_default = {}; // src/lang/locale/no.ts var no_default = {}; // src/lang/locale/pl.ts var pl_default = { // flashcard-modal.tsx DECKS: "Talie", DUE_CARDS: "Fiszki z terminem", NEW_CARDS: "Nowe fiszki", TOTAL_CARDS: "Wszystkie karty", BACK: "Wstecz", SKIP: "Pomi\u0144", EDIT_CARD: "Edytuj kart\u0119", RESET_CARD_PROGRESS: "Zresetuj post\u0119p karty", HARD: "Trudne", GOOD: "\u015Arednio Trudne", EASY: "\u0141atwe", SHOW_ANSWER: "Poka\u017C odpowied\u017A", CARD_PROGRESS_RESET: "Post\u0119p karty zosta\u0142 zresetowany.", SAVE: "Zapisz", CANCEL: "Anuluj", NO_INPUT: "Nie wprowadzono warto\u015Bci.", CURRENT_EASE_HELP_TEXT: "Aktualna \u0142atwo\u015B\u0107: ", CURRENT_INTERVAL_HELP_TEXT: "Aktualny interwa\u0142: ", CARD_GENERATED_FROM: "Wygenerowano z: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Otw\xF3rz notatk\u0119 do przegl\u0105du", REVIEW_CARDS: "Przegl\u0105daj fiszki", REVIEW_DIFFICULTY_FILE_MENU: "Przegl\u0105daj: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Przegl\u0105daj notatk\u0119 jako ${difficulty}", CRAM_ALL_CARDS: "Wybierz tali\u0119 do intensywnego uczenia", REVIEW_ALL_CARDS: "Przegl\u0105daj fiszki ze wszystkich notatek", REVIEW_CARDS_IN_NOTE: "Przegl\u0105daj fiszki w tej notatce", CRAM_CARDS_IN_NOTE: "Intensywne uczenie fiszek w tej notatce", VIEW_STATS: "Wy\u015Bwietl statystyki", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Przegl\u0105daj: ${dueNotesCount} notatek, ${dueFlashcardsCount} fiszek z terminem", SYNC_TIME_TAKEN: "Synchronizacja zaj\u0119\u0142a ${t}ms", NOTE_IN_IGNORED_FOLDER: "Notatka jest zapisana w folderze zignorowanym (sprawd\u017A ustawienia).", PLEASE_TAG_NOTE: "Prosz\u0119 odpowiednio otagowa\u0107 notatk\u0119 do przegl\u0105du (w ustawieniach).", RESPONSE_RECEIVED: "Otrzymano odpowied\u017A.", NO_DECK_EXISTS: "Nie istnieje talia o nazwie ${deckName}", ALL_CAUGHT_UP: "Jeste\u015B teraz na bie\u017C\u0105co :D.", // scheduling.ts DAYS_STR_IVL: "${interval} dni", MONTHS_STR_IVL: "${interval} miesi\u0119cy", YEARS_STR_IVL: "${interval} lata", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}r", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Aby uzyska\u0107 wi\u0119cej informacji, sprawd\u017A wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Foldery do zignorowania", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Fiszki", FLASHCARD_EASY_LABEL: "Tekst przycisku \u0141atwe", FLASHCARD_GOOD_LABEL: "Tekst przycisku \u015Arednio trudne", FLASHCARD_HARD_LABEL: "Tekst przycisku Trudne", FLASHCARD_EASY_DESC: 'Dostosuj etykiet\u0119 dla przycisku "\u0141atwe"', FLASHCARD_GOOD_DESC: 'Dostosuj etykiet\u0119 dla przycisku "\u015Arednio trudne"', FLASHCARD_HARD_DESC: 'Dostosuj etykiet\u0119 dla przycisku "Trudne"', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Tagi fiszek", FLASHCARD_TAGS_DESC: "Wprowad\u017A tagi oddzielone spacj\u0105 lub nowymi liniami, np. #fiszki #talia2 #talia3.", CONVERT_FOLDERS_TO_DECKS: "Czy konwertowa\u0107 foldery na talie i podtalie?", CONVERT_FOLDERS_TO_DECKS_DESC: "Jest to alternatywa dla opcji tag\xF3w fiszek powy\u017Cej.", INLINE_SCHEDULING_COMMENTS: "Czy zachowa\u0107 komentarz harmonogramowania w tej samej linii co ostatnia linia fiszki?", INLINE_SCHEDULING_COMMENTS_DESC: "W\u0142\u0105czenie tej opcji sprawi, \u017Ce komentarze HTML nie b\u0119d\u0105 przerywa\u0107 formatowania listy.", BURY_SIBLINGS_TILL_NEXT_DAY: "Czy ukrywa\u0107 karty rodze\u0144stwa do nast\u0119pnego dnia?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Rodze\u0144stwo to karty wygenerowane z tego samego tekstu karty, np. usuni\u0119cia zamaskowane", SHOW_CARD_CONTEXT: "Czy pokazywa\u0107 kontekst na kartach?", SHOW_CARD_CONTEXT_DESC: "np. Tytu\u0142 > Nag\u0142\xF3wek 1 > Podnag\u0142\xF3wek > ... > Podnag\u0142\xF3wek", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Procentowa wysoko\u015B\u0107 fiszki", CARD_MODAL_SIZE_PERCENT_DESC: "Powinno by\u0107 ustawione na 100% na urz\u0105dzeniach mobilnych lub gdy masz bardzo du\u017Ce obrazy", RESET_DEFAULT: "Zresetuj do domy\u015Blnych", CARD_MODAL_WIDTH_PERCENT: "Procentowa szeroko\u015B\u0107 fiszki", RANDOMIZE_CARD_ORDER: "Czy losowa\u0107 kolejno\u015B\u0107 kart podczas przegl\u0105du?", REVIEW_CARD_ORDER_WITHIN_DECK: "Kolejno\u015B\u0107 kart w talii wy\u015Bwietlana podczas przegl\u0105dania", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Kolejno w ramach talii (Najpierw wszystkie nowe karty)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Kolejno w ramach talii (Najpierw wszystkie karty z terminem)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Losowo w ramach talii (Najpierw wszystkie nowe karty)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Losowo w ramach talii (Najpierw wszystkie karty z terminem)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Losowa karta z losowej talii", REVIEW_DECK_ORDER: "Kolejno\u015B\u0107 talii wy\u015Bwietlana podczas przegl\u0105dania", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Kolejno (gdy wszystkie karty w poprzedniej talii przegl\u0105dni\u0119te)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Losowo (gdy wszystkie karty w poprzedniej talii przegl\u0105dni\u0119te)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Losowa karta z losowej talii", DISABLE_CLOZE_CARDS: "Wy\u0142\u0105czy\u0107 karty zamaskowane?", CONVERT_HIGHLIGHTS_TO_CLOZES: "Konwertowa\u0107 ==pod\u015Bwietlenia== na karty zamaskowane?", CONVERT_BOLD_TEXT_TO_CLOZES: "Konwertowa\u0107 pogrubiony tekst na karty zamaskowane?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Konwertowa\u0107 {{klamry}} na karty zamaskowane?", CLOZE_PATTERNS: "Wzory kart zamaskowanych", CLOZE_PATTERNS_DESC: 'Wprowad\u017A wzory kart zamaskowanych oddzielone nowymi liniami. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Separator dla kart zamaskowanych w linii", FIX_SEPARATORS_MANUALLY_WARNING: "Pami\u0119taj, \u017Ce po zmianie tego musisz r\u0119cznie edytowa\u0107 wszystkie karty zamaskowane, kt\xF3re ju\u017C masz.", INLINE_REVERSED_CARDS_SEPARATOR: "Separator dla kart zamaskowanych odwr\xF3conych w linii", MULTILINE_CARDS_SEPARATOR: "Separator dla kart zamaskowanych wieloliniowych", MULTILINE_REVERSED_CARDS_SEPARATOR: "Separator dla kart zamaskowanych odwr\xF3conych wieloliniowych", MULTILINE_CARDS_END_MARKER: "Caracteres que denotam o fim de clozes e flashcards multilineares", NOTES: "Notatki", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "W\u0142\u0105czy\u0107 panel przegl\u0105du notatek przy starcie", TAGS_TO_REVIEW: "Tagi do przegl\u0105du", TAGS_TO_REVIEW_DESC: "Wprowad\u017A tagi oddzielone spacj\u0105 lub nowymi liniami, np. #przegl\u0105d #tag2 #tag3.", OPEN_RANDOM_NOTE: "Otw\xF3rz losow\u0105 notatk\u0119 do przegl\u0105du", OPEN_RANDOM_NOTE_DESC: "Po wy\u0142\u0105czeniu tej opcji notatki s\u0105 uporz\u0105dkowane wed\u0142ug istotno\u015Bci (PageRank).", AUTO_NEXT_NOTE: "Automatycznie otwiera\u0107 nast\u0119pn\u0105 notatk\u0119 po przegl\u0105dzie", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Wy\u0142\u0105czy\u0107 opcje przegl\u0105du w menu pliku, tj. Przegl\u0105daj: \u0141atwe Dobrze Trudne", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Je\u015Bli wy\u0142\u0105czysz opcje przegl\u0105du w menu Plik, mo\u017Cesz przegl\u0105da\u0107 swoje notatki za pomoc\u0105 polece\u0144 wtyczki i, je\u015Bli je zdefiniowa\u0142e\u015B, przypisanych skr\xF3t\xF3w klawiszowych.", MAX_N_DAYS_REVIEW_QUEUE: "Maksymalna liczba dni do wy\u015Bwietlenia w panelu prawym", MIN_ONE_DAY: "Liczba dni musi wynosi\u0107 co najmniej 1.", VALID_NUMBER_WARNING: "Podaj prawid\u0142ow\u0105 liczb\u0119.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Podtalie powinny by\u0107 pocz\u0105tkowo wy\u015Bwietlane rozszerzone", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Wy\u0142\u0105cz to, aby zwin\u0105\u0107 zagnie\u017Cd\u017Cone talie w tej samej karcie. Przydatne, je\u015Bli karty nale\u017C\u0105 do wielu talii w tym samym pliku.", ALGORITHM: "Algorytm", CHECK_ALGORITHM_WIKI: 'Aby uzyska\u0107 wi\u0119cej informacji, sprawd\u017A implementacj\u0119 algorytmu.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Podstawowa \u0142atwo\u015B\u0107", BASE_EASE_DESC: "minimum = 130, preferowana warto\u015B\u0107 to oko\u0142o 250.", BASE_EASE_MIN_WARNING: "Podstawowa \u0142atwo\u015B\u0107 musi wynosi\u0107 co najmniej 130.", LAPSE_INTERVAL_CHANGE: "Zmiana interwa\u0142u podczas przegl\u0105dania fiszki/notatki jako trudne", LAPSE_INTERVAL_CHANGE_DESC: "nowyInterwa\u0142 = staryInterwa\u0142 * zmianaInterwa\u0142u / 100.", EASY_BONUS: "Bonus za \u0142atwe", EASY_BONUS_DESC: "Bonus za \u0142atwe pozwala ustawi\u0107 r\xF3\u017Cnic\u0119 w interwa\u0142ach mi\u0119dzy odpowiedziami \u015Arednio trudne i \u0141atwe na fiszce/notatce (minimum = 100%).", EASY_BONUS_MIN_WARNING: "Bonus za \u0142atwe musi wynosi\u0107 co najmniej 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maksymalny interwa\u0142 w dniach", MAX_INTERVAL_DESC: "Pozwala na ustawienie g\xF3rnego limitu interwa\u0142u (domy\u015Blnie = 100 lat).", MAX_INTERVAL_MIN_WARNING: "Maksymalny interwa\u0142 musi wynosi\u0107 co najmniej 1 dzie\u0144.", MAX_LINK_CONTRIB: "Maksymalny wk\u0142ad \u0142\u0105cza", MAX_LINK_CONTRIB_DESC: "Maksymalny wk\u0142ad wa\u017Conej \u0142atwo\u015Bci po\u0142\u0105czonych notatek do pocz\u0105tkowej \u0142atwo\u015Bci.", LOGGING: "Logowanie", DISPLAY_SCHEDULING_DEBUG_INFO: "Wy\u015Bwietl informacje debugowania w konsoli deweloperskiej", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Kolejka przegl\u0105du notatek", CLOSE: "Zamknij", NEW: "Nowe", YESTERDAY: "Wczoraj", TODAY: "Dzisiaj", TOMORROW: "Jutro", // stats-modal.tsx STATS_TITLE: "Statystyki", MONTH: "Miesi\u0105c", QUARTER: "Kwarta\u0142", YEAR: "Rok", LIFETIME: "Ca\u0142e \u017Cycie", FORECAST: "Prognoza", FORECAST_DESC: "Liczba kart z terminem w przysz\u0142o\u015Bci", SCHEDULED: "Zaplanowane", DAYS: "Dni", NUMBER_OF_CARDS: "Liczba kart", REVIEWS_PER_DAY: "\u015Arednio: ${avg} przegl\u0105d\xF3w/dzie\u0144", INTERVALS: "Interwa\u0142y", INTERVALS_DESC: "Op\xF3\u017Anienia przed ponownym pokazaniem przegl\u0105d\xF3w", COUNT: "Liczba", INTERVALS_SUMMARY: "\u015Aredni interwa\u0142: ${avg}, Najd\u0142u\u017Cszy interwa\u0142: ${longest}", EASES: "\u0141atwo\u015Bci", EASES_SUMMARY: "\u015Arednia \u0142atwo\u015B\u0107: ${avgEase}", EASE: "Ease", CARD_TYPES: "Typy kart", CARD_TYPES_DESC: "Obejmuje tak\u017Ce ukryte karty, je\u015Bli takie s\u0105", CARD_TYPE_NEW: "Nowe", CARD_TYPE_YOUNG: "M\u0142ode", CARD_TYPE_MATURE: "Stare", CARD_TYPES_SUMMARY: "\u0141\u0105czna liczba kart: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/pt.ts var pt_default = {}; // src/lang/locale/pt-br.ts var pt_br_default = { // flashcard-modal.tsx DECKS: "Baralhos", DUE_CARDS: "Cartas para Colocar em Dia", NEW_CARDS: "Novas Cartas", TOTAL_CARDS: "Total de Cartas", BACK: "Voltar", SKIP: "Pular", EDIT_CARD: "Editar Cart\xE3o", RESET_CARD_PROGRESS: "Reiniciar o Progresso da Carta", HARD: "Dif\xEDcil", GOOD: "OK", EASY: "F\xE1cil", SHOW_ANSWER: "Mostrar Resposta", CARD_PROGRESS_RESET: "O Progresso da Carta foi reiniciado", SAVE: "Salvar", CANCEL: "Cancelar", NO_INPUT: "Nenhuma entrada fornecida.", CURRENT_EASE_HELP_TEXT: "Facilidade atual: ", CURRENT_INTERVAL_HELP_TEXT: "Intervalo atual: ", CARD_GENERATED_FROM: "Gerada a partir de: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "Abrir uma nota para revisar", REVIEW_CARDS: "Revisar flashcards", REVIEW_DIFFICULTY_FILE_MENU: "Revis\xE3o: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Revisar nota como ${difficulty}", REVIEW_ALL_CARDS: "Revisar flashcards de todas as notas", CRAM_ALL_CARDS: "Selecione um baralho para revisar", REVIEW_CARDS_IN_NOTE: "Revisar flashcards nessa nota", CRAM_CARDS_IN_NOTE: "Revisar todas as flashcards nessa nota", VIEW_STATS: "Ver estat\xEDsticas", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "Revis\xE3o: ${dueNotesCount} nota(s), ${dueFlashcardsCount} Carta(s) para colocar em dia", SYNC_TIME_TAKEN: "Sincroniza\xE7\xE3o levou ${t}ms", NOTE_IN_IGNORED_FOLDER: "Nota \xE9 salva na pasta ignorada (cheque as configura\xE7\xF5es).", PLEASE_TAG_NOTE: "Por favor etiquete a nota apropriadamente para revisar (nas configura\xE7\xF5es).", RESPONSE_RECEIVED: "Resposta recebida.", NO_DECK_EXISTS: "Nenhum baralho existe para ${deckName}", ALL_CAUGHT_UP: "Voc\xEA colocou tudo em dia agora :D.", // scheduling.ts DAYS_STR_IVL: "${interval} dia(s)", MONTHS_STR_IVL: "${interval} m\xEAs(es)", YEARS_STR_IVL: "${interval} ano(s)", DAYS_STR_IVL_MOBILE: "${interval}d", MONTHS_STR_IVL_MOBILE: "${interval}m", YEARS_STR_IVL_MOBILE: "${interval}a", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: 'Para mais informa\xE7\xF5es, cheque a wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "Pastas para ignorar", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Flashcards", FLASHCARD_EASY_LABEL: "Texto do Bot\xE3o de F\xE1cil", FLASHCARD_GOOD_LABEL: "Texto do Bot\xE3o de OK", FLASHCARD_HARD_LABEL: "Texto do Bot\xE3o de Dif\xEDcil", FLASHCARD_EASY_DESC: 'Customize o r\xF3tulo para o bot\xE3o de "F\xE1cil"', FLASHCARD_GOOD_DESC: 'Customize o r\xF3tulo para o bot\xE3o de "OK"', FLASHCARD_HARD_DESC: 'Customize o r\xF3tulo para o bot\xE3o de "Dif\xEDcil"', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Etiquetas dos Flashcards", FLASHCARD_TAGS_DESC: "Insira etiquetas separadas por espa\xE7os ou quebras de linha ex: #flashcards #baralho2 #baralho3.", CONVERT_FOLDERS_TO_DECKS: "Converter pastas para baralhos e sub-baralhos?", CONVERT_FOLDERS_TO_DECKS_DESC: "Isso \xE9 uma alternativa para a op\xE7\xE3o de etiqueta dos Flashcards em cima.", INLINE_SCHEDULING_COMMENTS: "Salvar coment\xE1rios de agendamento na mesma linha que a \xFAltima linha do flashcard?", INLINE_SCHEDULING_COMMENTS_DESC: "Ligar isso vai fazer com que os coment\xE1rios em HTML n\xE3o quebrem a formata\xE7\xE3o de listas.", BURY_SIBLINGS_TILL_NEXT_DAY: "Enterrar cartas irm\xE3s at\xE9 o pr\xF3ximo dia?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Cartas irm\xE3s s\xE3o geradas pelo texto da mesma carta ex: omiss\xE3o de palavras", SHOW_CARD_CONTEXT: "Mostrar contexto nas cartas?", SHOW_CARD_CONTEXT_DESC: "ex: T\xEDtulo > Cabe\xE7alho 1 > Subcabe\xE7alho > ... > Subcabe\xE7alho", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Porcentagem da Altura do Flashcard", CARD_MODAL_SIZE_PERCENT_DESC: "Deveria estar configurado em 100% em dispositivos m\xF3veis ou se voc\xEA tem imagens muito grandes", RESET_DEFAULT: "Reiniciar para a pr\xE9-defini\xE7\xE3o", CARD_MODAL_WIDTH_PERCENT: "Porcentagem de Largura do Flashcard", RANDOMIZE_CARD_ORDER: "Aleatorizar a ordem das cartas durante a revis\xE3o?", REVIEW_CARD_ORDER_WITHIN_DECK: "Order cards in a deck are displayed during review", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "Sequentially within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "Sequentially within a deck (All due cards first)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Randomly within a deck (All new cards first)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Randomly within a deck (All due cards first)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", REVIEW_DECK_ORDER: "Order decks are displayed during review", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "Sequentially (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Randomly (once all cards in previous deck reviewed)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Random card from random deck", DISABLE_CLOZE_CARDS: "Desabilitar cartas que usam omiss\xE3o de palavras?", CONVERT_HIGHLIGHTS_TO_CLOZES: "Converter ==marca-texto== em omiss\xF5es?", CONVERT_BOLD_TEXT_TO_CLOZES: "Converter **texto em negrito** em omiss\xF5es?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "Converter {{chaves}} em omiss\xF5es?", CLOZE_PATTERNS: "Padr\xF5es de Omiss\xE3o", CLOZE_PATTERNS_DESC: 'Entre os padr\xF5es de omiss\xE3o separados por quebras de linha. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Separador para flashcards inline", FIX_SEPARATORS_MANUALLY_WARNING: "Note que depois de mudar isso voc\xEA vai ter que manualmente mudar quaisquer flashcards que voc\xEA tenha.", INLINE_REVERSED_CARDS_SEPARATOR: "Separador para flashcards inline reversos", MULTILINE_CARDS_SEPARATOR: "Separador para flashcards de m\xFAltiplas linhas", MULTILINE_REVERSED_CARDS_SEPARATOR: "Separador para flashcards de m\xFAltiplas linhas reversos", MULTILINE_CARDS_END_MARKER: "Caracteres que denotam o fim de clozes e flashcards multilinha", NOTES: "Notas", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Habilitar painel de revis\xE3o de notas na inicializa\xE7\xE3o", TAGS_TO_REVIEW: "Etiquetas para revisar", TAGS_TO_REVIEW_DESC: "Insira etiquetas separadas por espa\xE7os ou quebra de linhas ex: #revisar #etiqueta2 #etiqueta3.", OPEN_RANDOM_NOTE: "Abrir uma nota aleat\xF3ria para revisar", OPEN_RANDOM_NOTE_DESC: "Quando voc\xEA desabilitar isso, as notas v\xE3o ser ordenadas por import\xE2ncia (PageRank).", AUTO_NEXT_NOTE: "Abrir a pr\xF3xima nota automaticamente depois de uma revis\xE3o", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Ative as op\xE7\xF5es de revis\xE3o no menu Arquivo (ex.: Revis\xE3o: F\xE1cil, OK, Dif\xEDcil)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "Se voc\xEA desativar as op\xE7\xF5es de revis\xE3o no menu Arquivo, poder\xE1 revisar suas anota\xE7\xF5es usando os comandos do plugin e, se os tiver definido, as teclas de atalho associadas.", MAX_N_DAYS_REVIEW_QUEUE: "N\xFAmero m\xE1ximo de dias para exibir no painel direito", MIN_ONE_DAY: "O n\xFAmero de dias deve ser pelo menos 1.", VALID_NUMBER_WARNING: "Por favor Insira um n\xFAmero v\xE1lido.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\xC1rvores de baralhos devem inicialmente ser exibidas como expandidas", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Desabilite isso para colapsar baralhos que est\xE3o um dentro do outro na mesma carta. \xDAtil se voc\xEA tem cartas que pertencem a muitos baralhos em um mesmo arquivo.", ALGORITHM: "Algor\xEDtmo", CHECK_ALGORITHM_WIKI: 'Para mais informa\xE7\xF5es, cheque a implementa\xE7\xE3o do algor\xEDtmo.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Facilidade base", BASE_EASE_DESC: "m\xEDnimo = 130, preferivelmente por volta de 250.", BASE_EASE_MIN_WARNING: "A facilidade base deve ser pelo menos 130.", LAPSE_INTERVAL_CHANGE: "Mudan\xE7a de intervalo quando voc\xEA revisa um(a) flashcard/nota como dif\xEDcil", LAPSE_INTERVAL_CHANGE_DESC: "novoIntervalo = velhoIntervalo * mudancaIntervalo / 100.", EASY_BONUS: "B\xF4nus de F\xE1cil", EASY_BONUS_DESC: "O b\xF4nus de f\xE1cil te permite mudar a difer\xEAncia entre intervalos de responder OK e F\xE1cil em um(a) flashcard/nota (m\xEDnimo = 100%).", EASY_BONUS_MIN_WARNING: "O b\xF4nus de f\xE1cil deve ser pelo menos 100.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Intervalo m\xE1ximo em dias", MAX_INTERVAL_DESC: "Te permite colocar um limite m\xE1ximo no intervalo (pr\xE9-defini\xE7\xE3o = 100 anos).", MAX_INTERVAL_MIN_WARNING: "O intervalo m\xE1ximo deve ser pelo menos 1 dia.", MAX_LINK_CONTRIB: "Contribui\xE7\xE3o M\xE1xima de Links", MAX_LINK_CONTRIB_DESC: "Contribui\xE7\xE3o m\xE1xima da facilidade ponderada das notas linkadas \xE0 facilidade inicial.", LOGGING: "Logging", DISPLAY_SCHEDULING_DEBUG_INFO: "Mostrar informa\xE7\xE3o de debugging no console de desenvolvimento", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Fila de Notas para Revisar", CLOSE: "Fechar", NEW: "Novo", YESTERDAY: "Ontem", TODAY: "Hoje", TOMORROW: "Amanh\xE3", // stats-modal.tsx STATS_TITLE: "Estat\xEDsticas", MONTH: "M\xEAs", QUARTER: "Trimestre", YEAR: "Ano", LIFETIME: "Tempo Total", FORECAST: "Previs\xE3o", FORECAST_DESC: "O n\xFAmero de cartas a serem colocadas em dia no futuro", SCHEDULED: "Agendado", DAYS: "Dias", NUMBER_OF_CARDS: "N\xFAmero de cartas", REVIEWS_PER_DAY: "M\xE9dia: ${avg} revis\xF5es/dia", INTERVALS: "Intervalos", INTERVALS_DESC: "Atrasos at\xE9 que as revis\xF5es sejam exibidas de novo", COUNT: "Contagem", INTERVALS_SUMMARY: "Intervalo em m\xE9dia: ${avg}, Maior intervalo: ${longest}", EASES: "Facilidades", EASES_SUMMARY: "Facilidade em m\xE9dia: ${avgEase}", EASE: "Ease", CARD_TYPES: "Tipos de Cartas", CARD_TYPES_DESC: "Isso tamb\xE9m inclui cartas enterradas, caso existam", CARD_TYPE_NEW: "Novo", CARD_TYPE_YOUNG: "Jovem", CARD_TYPE_MATURE: "Amadurecido", CARD_TYPES_SUMMARY: "Total de cartas: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/ro.ts var ro_default = {}; // src/lang/locale/ru.ts var ru_default = { // flashcard-modal.tsx DECKS: "\u041A\u043E\u043B\u043E\u0434\u044B", DUE_CARDS: "\u041F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u043C\u044B\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", NEW_CARDS: "\u041D\u043E\u0432\u044B\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", TOTAL_CARDS: "\u0412\u0441\u0435\u0433\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", BACK: "\u041D\u0430\u0437\u0430\u0434", SKIP: "\u041F\u0440\u043E\u043F\u0443\u0441\u0442\u0438\u0442\u044C", EDIT_CARD: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0443", RESET_CARD_PROGRESS: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u043F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", HARD: "\u0421\u043B\u043E\u0436\u043D\u043E", GOOD: "\u041D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E", EASY: "\u041B\u0435\u0433\u043A\u043E", SHOW_ANSWER: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043E\u0442\u0432\u0435\u0442", CARD_PROGRESS_RESET: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u043F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", SAVE: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C", CANCEL: "\u041E\u0442\u043C\u0435\u043D\u0430", NO_INPUT: "\u041F\u0443\u0441\u0442\u043E\u0439 \u0432\u0432\u043E\u0434.", CURRENT_EASE_HELP_TEXT: "\u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u043F\u0440\u043E\u0433\u0440\u0435\u0441\u0441: ", CURRENT_INTERVAL_HELP_TEXT: "\u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B: ", CARD_GENERATED_FROM: "\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E \u0438\u0437: ${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0437\u0430\u043C\u0435\u0442\u043A\u0443 \u0434\u043B\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", REVIEW_CARDS: "\u0418\u0437\u0443\u0447\u0430\u0442\u044C \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", REVIEW_DIFFICULTY_FILE_MENU: "\u0418\u0437\u0443\u0447\u0435\u043D\u0438\u0435: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "\u0418\u0437\u0443\u0447\u0430\u0442\u044C \u0437\u0430\u043C\u0435\u0442\u043A\u0443 \u043A\u0430\u043A ${difficulty}", CRAM_ALL_CARDS: "\u0417\u0443\u0431\u0440\u0438\u0442\u044C \u0432\u0441\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432 \u044D\u0442\u043E\u0439 \u043A\u043E\u043B\u043E\u0434\u0435", REVIEW_ALL_CARDS: "\u0418\u0437\u0443\u0447\u0430\u0442\u044C \u0432\u0441\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432\u043E \u0432\u0441\u0435\u0445 \u0437\u0430\u043C\u0435\u0442\u043A\u0430\u0445", REVIEW_CARDS_IN_NOTE: "\u0418\u0437\u0443\u0447\u0430\u0442\u044C \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432 \u044D\u0442\u043E\u0439 \u0437\u0430\u043C\u0435\u0442\u043A\u0435", CRAM_CARDS_IN_NOTE: "\u0417\u0443\u0431\u0440\u0438\u0442\u044C \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432 \u044D\u0442\u043E\u0439 \u0437\u0430\u043C\u0435\u0442\u043A\u0435", VIEW_STATS: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0443", OPEN_REVIEW_QUEUE_VIEW: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u043E\u0447\u0435\u0440\u0435\u0434\u044C \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F \u0437\u0430\u043C\u0435\u0442\u043E\u043A \u043D\u0430 \u0431\u043E\u043A\u043E\u0432\u043E\u0439 \u043F\u0430\u043D\u0435\u043B\u0438", STATUS_BAR: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C: ${dueNotesCount} \u0437\u0430\u043C\u0435\u0442\u043E\u043A, ${dueFlashcardsCount} \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", SYNC_TIME_TAKEN: "\u0421\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u044F \u0437\u0430\u043D\u044F\u043B\u0430 ${t}\u043C\u0441", NOTE_IN_IGNORED_FOLDER: "\u0417\u0430\u043C\u0435\u0442\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0430 \u0432 \u0438\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u043C\u0443\u044E \u043F\u0430\u043F\u043A\u0443 (\u0441\u043C. \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438).", PLEASE_TAG_NOTE: "\u0414\u043B\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F, \u043F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E \u043F\u043E\u043C\u0435\u0442\u044C\u0442\u0435 \u0437\u0430\u043C\u0435\u0442\u043A\u0443 \u0442\u0435\u0433\u043E\u043C (\u0441\u043C. \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438).", RESPONSE_RECEIVED: "\u041E\u0442\u0432\u0435\u0442 \u043F\u043E\u043B\u0443\u0447\u0435\u043D.", NO_DECK_EXISTS: "\u041D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0443\u0440\u043E\u0432\u043D\u044F ${deckName}", ALL_CAUGHT_UP: "\u041C\u043E\u043B\u043E\u0434\u0435\u0446! \u0422\u044B \u0441\u043F\u0440\u0430\u0432\u0438\u043B\u0441\u044F \u0438 \u0434\u043E\u0448\u0435\u043B \u0434\u043E \u043A\u043E\u043D\u0446\u0430! :D", // scheduling.ts DAYS_STR_IVL: "${interval} \u0434\u043D\u0435\u0439", MONTHS_STR_IVL: "${interval} \u043C\u0435\u0441\u044F\u0446\u0435\u0432", YEARS_STR_IVL: "${interval} \u0433\u043E\u0434\u043E\u0432", DAYS_STR_IVL_MOBILE: "${interval}\u0434.", MONTHS_STR_IVL_MOBILE: "${interval}\u043C.", YEARS_STR_IVL_MOBILE: "${interval}\u0433.", // settings.ts SETTINGS_HEADER: "Spaced Repetition", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '\u0414\u043B\u044F \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435: wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\u0418\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u043C\u044B\u0435 \u043F\u0430\u043F\u043A\u0438", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", FLASHCARD_EASY_LABEL: '\u0422\u0435\u043A\u0441\u0442 \u043A\u043D\u043E\u043F\u043A\u0438 "\u041B\u0435\u0433\u043A\u043E"', FLASHCARD_GOOD_LABEL: '\u0422\u0435\u043A\u0441\u0442 \u043A\u043D\u043E\u043F\u043A\u0438 "\u041D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E"', FLASHCARD_HARD_LABEL: '\u0422\u0435\u043A\u0441\u0442 \u043A\u043D\u043E\u043F\u043A\u0438 "\u0421\u043B\u043E\u0436\u043D\u043E"', FLASHCARD_EASY_DESC: '\u041D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u044F\u0440\u043B\u044B\u043A \u0434\u043B\u044F \u043A\u043D\u043E\u043F\u043A\u0438 "\u041B\u0435\u0433\u043A\u043E"', FLASHCARD_GOOD_DESC: '\u041D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u044F\u0440\u043B\u044B\u043A \u0434\u043B\u044F \u043A\u043D\u043E\u043F\u043A\u0438 "\u041D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E"', FLASHCARD_HARD_DESC: '\u041D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u044F\u0440\u043B\u044B\u043A \u0434\u043B\u044F \u043A\u043D\u043E\u043F\u043A\u0438 "\u0421\u043B\u043E\u0436\u043D\u043E"', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\u0422\u0435\u0433\u0438 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", FLASHCARD_TAGS_DESC: "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0442\u0435\u0433\u0438 \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435 Enter-\u043E\u043C \u0438\u043B\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u043C, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: #flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0438 \u0432 \u0443\u0440\u043E\u0432\u043D\u0438 \u0438 \u043F\u043E\u0434\u0443\u0440\u043E\u0432\u043D\u0438?", CONVERT_FOLDERS_TO_DECKS_DESC: "\u042D\u0442\u043E \u0430\u043B\u044C\u0442\u0435\u0440\u043D\u0430\u0442\u0438\u0432\u0430 \u043E\u043F\u0438\u0441\u0430\u043D\u043D\u043E\u043C\u0443 \u0432\u044B\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0443 \u0442\u0435\u0433\u043E\u0432 \u0444\u043B\u044D\u0448-\u043A\u0430\u0440\u0442", INLINE_SCHEDULING_COMMENTS: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u043F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043D\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438?", INLINE_SCHEDULING_COMMENTS_DESC: "\u0412\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u044D\u0442\u043E\u0439 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0441\u0434\u0435\u043B\u0430\u0435\u0442 \u0442\u0430\u043A, \u0447\u0442\u043E HTML \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438 \u043D\u0435 \u0431\u0443\u0434\u0443\u0442 \u043B\u043E\u043C\u0430\u0442\u044C \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0441\u043F\u0438\u0441\u043A\u0430.", BURY_SIBLINGS_TILL_NEXT_DAY: "\u041F\u0440\u044F\u0442\u0430\u0442\u044C \u0440\u043E\u0434\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0434\u043E \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0433\u043E \u0434\u043D\u044F?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "\u0420\u043E\u0434\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 - \u0442\u0435, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u044B \u0438\u0437 \u043E\u0434\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430, \u043F\u0440\u0438\u043C\u0435\u0440: \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0441 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u043C\u0438 ([...])", SHOW_CARD_CONTEXT: "\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 (\u0443\u0440\u043E\u0432\u0435\u043D\u044C) \u0432 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430\u0445 (\u0432\u043E \u0432\u0440\u0435\u043C\u044F \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F)?", SHOW_CARD_CONTEXT_DESC: "\u043F\u0440\u0438\u043C\u0435\u0440: Title > Heading 1 > Subheading > ... > Subheading", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\u0412\u044B\u0441\u043E\u0442\u0430 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432 \u043F\u0440\u043E\u0446\u0435\u043D\u0442\u0430\u0445", CARD_MODAL_SIZE_PERCENT_DESC: "\u0415\u0441\u043B\u0438 \u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435\u0441\u044C \u043C\u043E\u0431\u0438\u043B\u044C\u043D\u044B\u043C \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u043E\u043C, \u0432\u044B\u0441\u0442\u0430\u0432\u044C\u0442\u0435 100%. \u0418\u043D\u0430\u0447\u0435 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u043E\u0433\u0440\u043E\u043C\u043D\u044B\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F", RESET_DEFAULT: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043F\u043E-\u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E", CARD_MODAL_WIDTH_PERCENT: "\u0428\u0438\u0440\u0438\u043D\u0430 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u0432 \u043F\u0440\u043E\u0446\u0435\u043D\u0442\u0430\u0445", RANDOMIZE_CARD_ORDER: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u044B\u0439 \u043F\u043E\u0440\u044F\u0434\u043E\u043A \u043A\u0430\u0440\u0442 \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F?", REVIEW_CARD_ORDER_WITHIN_DECK: "\u041F\u043E\u0440\u044F\u0434\u043E\u043A \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u043A\u0430\u0440\u0442 \u043A\u043E\u043B\u043E\u0434\u044B \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "\u041F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u0432\u043D\u0443\u0442\u0440\u0438 \u043A\u043E\u043B\u043E\u0434\u044B (\u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0441\u0435 \u043D\u043E\u0432\u044B\u0435 \u043A\u0430\u0440\u0442\u044B)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "\u041F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u0432\u043D\u0443\u0442\u0440\u0438 \u043A\u043E\u043B\u043E\u0434\u044B (\u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0441\u0435 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u043C\u044B\u0435 \u043A\u0430\u0440\u0442\u044B)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u043E \u0432\u043D\u0443\u0442\u0440\u0438 \u043A\u043E\u043B\u043E\u0434\u044B (\u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0441\u0435 \u043D\u043E\u0432\u044B\u0435 \u043A\u0430\u0440\u0442\u044B)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u043E \u0432\u043D\u0443\u0442\u0440\u0438 \u043A\u043E\u043B\u043E\u0434\u044B (\u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0441\u0435 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u043C\u044B\u0435 \u043A\u0430\u0440\u0442\u044B)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u0430\u044F \u043A\u0430\u0440\u0442\u0430 \u0438\u0437 \u0441\u043B\u0443\u0447\u0430\u0439\u043D\u043E\u0439 \u043A\u043E\u043B\u043E\u0434\u044B", REVIEW_DECK_ORDER: "\u041F\u043E\u0440\u044F\u0434\u043E\u043A \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u043E\u0434 \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "\u041F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E (\u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u0432\u0441\u0435\u0445 \u043A\u0430\u0440\u0442 \u0438\u0437 \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u0439 \u043A\u043E\u043B\u043E\u0434\u044B)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u043E (\u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u0432\u0441\u0435\u0445 \u043A\u0430\u0440\u0442 \u0438\u0437 \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u0439 \u043A\u043E\u043B\u043E\u0434\u044B)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "\u0421\u043B\u0443\u0447\u0430\u0439\u043D\u0430\u044F \u043A\u0430\u0440\u0442\u0430 \u0438\u0437 \u0441\u043B\u0443\u0447\u0430\u0439\u043D\u043E\u0439 \u043A\u043E\u043B\u043E\u0434\u044B", DISABLE_CLOZE_CARDS: "\u0412\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043A\u0430\u0440\u0442\u044B \u0441 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u043C\u0438 (\u043F\u0440\u0438\u043C\u0435\u0440: [...])?", CONVERT_HIGHLIGHTS_TO_CLOZES: "\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C ==\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442== \u0432 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0438 (\u043F\u0440\u0438\u043C\u0435\u0440: [...])?", CONVERT_BOLD_TEXT_TO_CLOZES: "\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C **\u0436\u0438\u0440\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442** \u0432 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0438 (\u043F\u0440\u0438\u043C\u0435\u0440: [...])?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C {{\u0444\u0438\u0433\u0443\u0440\u043D\u044B\u0435 \u0441\u043A\u043E\u0431\u043A\u0438}} \u0432 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0438 (\u043F\u0440\u0438\u043C\u0435\u0440: [...])?", CLOZE_PATTERNS: "\u0428\u0430\u0431\u043B\u043E\u043D\u044B \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u043E\u0432", CLOZE_PATTERNS_DESC: '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u044B \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u043E\u0432, \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0432\u043E\u0434\u0430\u043C\u0438 \u0441\u0442\u0440\u043E\u043A. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0434\u043B\u044F \u0432\u043D\u0443\u0442\u0440\u0438\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0445 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", FIX_SEPARATORS_MANUALLY_WARNING: "\u0412\u043D\u0438\u043C\u0430\u043D\u0438\u0435! \u041F\u043E\u0441\u043B\u0435 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u044D\u0442\u043E\u0433\u043E \u0432\u0430\u043C \u043F\u0440\u0438\u0434\u0451\u0442\u0441\u044F \u0432\u0440\u0443\u0447\u043D\u0443\u044E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438", INLINE_REVERSED_CARDS_SEPARATOR: "\u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0434\u043B\u044F \u043E\u0431\u0440\u0430\u0442\u043D\u044B\u0445 \u0432\u043D\u0443\u0442\u0440\u0438\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0445 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", MULTILINE_CARDS_SEPARATOR: "\u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0434\u043B\u044F \u043C\u043D\u043E\u0433\u043E\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0445 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", MULTILINE_REVERSED_CARDS_SEPARATOR: "\u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0434\u043B\u044F \u043E\u0431\u0440\u0430\u0442\u043D\u044B\u0445 \u043C\u043D\u043E\u0433\u043E\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0445 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", MULTILINE_CARDS_END_MARKER: "\u0421\u0438\u043C\u0432\u043E\u043B\u044B, \u043E\u0431\u043E\u0437\u043D\u0430\u0447\u0430\u044E\u0449\u0438\u0435 \u043A\u043E\u043D\u0435\u0446 \u043A\u043B\u043E\u0437\u043E\u0432 \u0438 \u043C\u043D\u043E\u0433\u043E\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0445 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", NOTES: "\u0417\u0430\u043C\u0435\u0442\u043A\u0438", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0430\u043D\u0435\u043B\u044C \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B", TAGS_TO_REVIEW: "\u0422\u0435\u0433\u0438 \u0434\u043B\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", TAGS_TO_REVIEW_DESC: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u0433\u0438, \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435 Enter-\u0430\u043C\u0438 \u0438\u043B\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C\u0438, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0441\u043B\u0443\u0447\u0430\u0439\u043D\u0443\u044E \u0437\u0430\u043C\u0435\u0442\u043A\u0443 \u0434\u043B\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", OPEN_RANDOM_NOTE_DESC: "\u0415\u0441\u043B\u0438 \u0432\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C, \u0442\u043E \u0437\u0430\u043C\u0435\u0442\u043A\u0438 \u0431\u0443\u0434\u0443\u0442 \u043E\u0442\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u044B \u043F\u043E \u0432\u0430\u0436\u043D\u043E\u0441\u0442\u0438 (PageRank).", AUTO_NEXT_NOTE: "\u041F\u043E\u0441\u043B\u0435 \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0442\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u0437\u0430\u043C\u0435\u0442\u043A\u0443", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043E\u0431\u0437\u043E\u0440\u0430 \u0432 \u043C\u0435\u043D\u044E \u0424\u0430\u0439\u043B (\u0442.\u0435.: \u0418\u0437\u0443\u0447\u0435\u043D\u0438\u0435: \u041B\u0435\u0433\u043A\u043E, \u041D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E, \u0421\u043B\u043E\u0436\u043D\u043E)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\u0415\u0441\u043B\u0438 \u0432\u044B \u043E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043E\u0431\u0437\u043E\u0440\u0430 \u0432 \u043C\u0435\u043D\u044E \u0424\u0430\u0439\u043B, \u0432\u044B \u0441\u043C\u043E\u0436\u0435\u0442\u0435 \u043F\u0440\u043E\u0441\u043C\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044C \u0441\u0432\u043E\u0438 \u0437\u0430\u043C\u0435\u0442\u043A\u0438 \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u043A\u043E\u043C\u0430\u043D\u0434 \u043F\u043B\u0430\u0433\u0438\u043D\u0430 \u0438, \u0435\u0441\u043B\u0438 \u0432\u044B \u0438\u0445 \u0437\u0430\u0434\u0430\u043B\u0438, \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0445 \u0433\u043E\u0440\u044F\u0447\u0438\u0445 \u043A\u043B\u0430\u0432\u0438\u0448.", MAX_N_DAYS_REVIEW_QUEUE: "\u041D\u0430\u0438\u0431\u043E\u043B\u044C\u0448\u0435\u0435 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u043D\u0435\u0439 \u0434\u043B\u044F \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0430 \u043F\u0430\u043D\u0435\u043B\u0438 \u0441\u043F\u0440\u0430\u0432\u0430", MIN_ONE_DAY: "\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u043D\u0435\u0439 \u043D\u0435 \u043C\u0435\u043D\u044C\u0448\u0435 1.", VALID_NUMBER_WARNING: "\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043F\u043E\u0434\u0445\u043E\u0434\u044F\u0449\u0435\u0435 \u0447\u0438\u0441\u043B\u043E.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\u0414\u0435\u0440\u0435\u0432\u044C\u044F \u043A\u043E\u043B\u043E\u0434 \u0434\u043E\u043B\u0436\u043D\u044B \u0438\u0437\u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F \u043A\u0430\u043A \u0440\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044B\u0435", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "\u041E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u044D\u0442\u043E\u0442 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440, \u0447\u0442\u043E\u0431\u044B \u0441\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u043B\u043E\u0436\u0435\u043D\u043D\u044B\u0435 \u043A\u043E\u043B\u043E\u0434\u044B \u043D\u0430 \u043E\u0434\u043D\u043E\u0439 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0435. \u041F\u043E\u043B\u0435\u0437\u043D\u043E, \u0435\u0441\u043B\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044C \u043A\u0430\u0440\u0442\u044B, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043F\u0440\u0438\u043D\u0430\u0434\u043B\u0435\u0436\u0430\u0442 \u043C\u043D\u043E\u0433\u0438\u043C \u043A\u043E\u043B\u043E\u0434\u0430\u043C \u0432 \u043E\u0434\u043D\u043E\u043C \u0444\u0430\u0439\u043B\u0435.", ALGORITHM: "\u0410\u043B\u0433\u043E\u0440\u0438\u0442\u043C", CHECK_ALGORITHM_WIKI: '\u0417\u0430 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0435\u0439 \u043E\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044C \u043A \u0440\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0430.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\u0411\u0430\u0437\u043E\u0432\u0430\u044F \u041B\u0451\u0433\u043A\u043E\u0441\u0442\u044C", BASE_EASE_DESC: "\u043C\u0438\u043D\u0438\u043C\u0443\u043C = 130, \u043F\u0440\u0435\u0434\u043F\u043E\u0447\u0442\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043E\u043A\u043E\u043B\u043E 250.", BASE_EASE_MIN_WARNING: "\u041B\u0451\u0433\u043A\u043E\u0441\u0442\u044C \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043C\u0438\u043D\u0438\u043C\u0443\u043C 130.", LAPSE_INTERVAL_CHANGE: '\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430 \u043F\u0440\u0438 \u0432\u044B\u0431\u043E\u0440\u0435 "\u0421\u043B\u043E\u0436\u043D\u043E" \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438/\u0437\u0430\u043C\u0435\u0442\u043A\u0438', LAPSE_INTERVAL_CHANGE_DESC: "\u043D\u043E\u0432\u044B\u0439\u041F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u043A = \u0441\u0442\u0430\u0440\u044B\u0439\u041F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u043A * \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435\u041F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043A\u0430 / 100.", EASY_BONUS: "\u041B\u0435\u0433\u043A\u043E: \u0431\u043E\u043D\u0443\u0441", EASY_BONUS_DESC: "\u0411\u043E\u043D\u0443\u0441 \u0437\u0430 \u041B\u0435\u0433\u043A\u043E \u043F\u043E\u0437\u0432\u043E\u043B\u044F\u0435\u0442 \u0432\u0430\u043C \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0440\u0430\u0437\u043D\u0438\u0446\u0443 \u0432 \u043F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043A\u0430\u0445 \u043C\u0435\u0436\u0434\u0443 \u043E\u0442\u0432\u0435\u0442\u0430\u043C\u0438 \u0425\u043E\u0440\u043E\u0448\u043E \u0438 \u041B\u0435\u0433\u043A\u043E \u043D\u0430 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0435/\u0437\u0430\u043C\u0435\u0442\u043A\u0435 (\u043C\u0438\u043D. = 100%).", EASY_BONUS_MIN_WARNING: '\u0411\u043E\u043D\u0443\u0441 \u0437\u0430 "\u041B\u0435\u0433\u043A\u043E" \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u043C\u0435\u043D\u044C\u0448\u0435 100.', LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F \u0432 \u0434\u043D\u044F\u0445", MAX_INTERVAL_DESC: "\u041F\u043E\u0437\u0432\u043E\u043B\u044F\u0435\u0442 \u0432\u0430\u043C \u0443\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0442\u044C \u0432\u0435\u0440\u0445\u043D\u044E\u044E \u0433\u0440\u0430\u043D\u0438\u0446\u0443 \u043D\u0430 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E = 100 \u043B\u0435\u0442).", MAX_INTERVAL_MIN_WARNING: "\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u043C\u0435\u043D\u044C\u0448\u0435 1.", MAX_LINK_CONTRIB: "\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0432\u043A\u043B\u0430\u0434 \u0441\u0432\u044F\u0437\u0438 (\u0441\u0441\u044B\u043B\u043A\u0438)", MAX_LINK_CONTRIB_DESC: '\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0432\u043A\u043B\u0430\u0434 \u0441\u0440\u0435\u0434\u043D\u0435\u0433\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F "\u041B\u0451\u0433\u043A\u043E\u0441\u0442\u0438" \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0445 \u0437\u0430\u043C\u0435\u0442\u043E\u043A \u0432 \u043D\u0430\u0447\u0430\u043B\u044C\u043D\u0443\u044E "\u041B\u0451\u0433\u043A\u043E\u0441\u0442\u044C".', LOGGING: "\u0416\u0443\u0440\u043D\u0430\u043B\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435", DISPLAY_SCHEDULING_DEBUG_INFO: "\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u043E\u0442\u043B\u0430\u0434\u043E\u0447\u043D\u0443\u044E \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E \u0432 \u043A\u043E\u043D\u0441\u043E\u043B\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0430", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\u041E\u0447\u0435\u0440\u0435\u0434\u044C \u0437\u0430\u043C\u0435\u0442\u043E\u043A \u043D\u0430 \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u0435", CLOSE: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", NEW: "\u041D\u043E\u0432\u044B\u0435", YESTERDAY: "\u0412\u0447\u0435\u0440\u0430\u0448\u043D\u0438\u0435", TODAY: "\u0421\u0435\u0433\u043E\u0434\u043D\u044F\u0448\u043D\u0438\u0435", TOMORROW: "\u0417\u0430\u0432\u0442\u0440\u0430\u0448\u043D\u0438\u0435", // stats-modal.tsx STATS_TITLE: "\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430", MONTH: "\u041C\u0435\u0441\u044F\u0446", QUARTER: "\u041A\u0432\u0430\u0440\u0442\u0430\u043B", YEAR: "\u0413\u043E\u0434", LIFETIME: "\u0412\u0441\u0451 \u0432\u0440\u0435\u043C\u044F", FORECAST: "\u041F\u0440\u043E\u0433\u043D\u043E\u0437", FORECAST_DESC: "\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A \u043F\u0440\u0435\u0434\u0441\u0442\u043E\u044F\u0449\u0438\u0445 \u0434\u043B\u044F \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F", SCHEDULED: "\u0417\u0430\u043F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u043E", DAYS: "\u0414\u043D\u0438", NUMBER_OF_CARDS: "\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", REVIEWS_PER_DAY: "\u0421\u0440\u0435\u0434\u043D\u0435\u0435 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E: ${avg} \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u0439 \u0432 \u0434\u0435\u043D\u044C", INTERVALS: "\u0418\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u044B", INTERVALS_DESC: "\u041F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043A\u0438 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0434\u043E \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0433\u043E \u043F\u043E\u043A\u0430\u0437\u0430 \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044F", COUNT: "\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E", INTERVALS_SUMMARY: "\u0421\u0440\u0435\u0434\u043D\u0438\u0439 \u043F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u043A: ${avg}, \u0421\u0430\u043C\u044B\u0439 \u0434\u043B\u0438\u043D\u043D\u044B\u0439 \u043F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u043A: ${longest}", EASES: "\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u0438\u0437\u0443\u0447\u0435\u043D\u0438\u044F", EASES_SUMMARY: "\u0421\u0440\u0435\u0434\u043D\u0435\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0433\u0440\u0435\u0441\u0441\u0430: ${avgEase}", EASE: "Ease", CARD_TYPES: "\u0422\u0438\u043F\u044B \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A", CARD_TYPES_DESC: "\u0412\u043A\u043B\u044E\u0447\u0430\u044F \u0441\u043F\u0440\u044F\u0442\u0430\u043D\u043D\u044B\u0435 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438, \u0435\u0441\u043B\u0438 \u0442\u0430\u043A\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0442.", CARD_TYPE_NEW: "\u041D\u043E\u0432\u044B\u0445", CARD_TYPE_YOUNG: "\u041F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u043C\u044B\u0445", CARD_TYPE_MATURE: "\u0418\u0437\u0443\u0447\u0435\u043D\u043D\u044B\u0445", CARD_TYPES_SUMMARY: "\u0412\u0441\u0435\u0433\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/sw.ts var sw_default = {}; // src/lang/locale/ta.ts var ta_default = {}; // src/lang/locale/te.ts var te_default = {}; // src/lang/locale/th.ts var th_default = {}; // src/lang/locale/tr.ts var tr_default = { // flashcard-modal.tsx DECKS: "Desteler", DUE_CARDS: "G\xFCncel Kartlar", NEW_CARDS: "Yeni Kartlar", TOTAL_CARDS: "Toplam Kartlar", BACK: "Geri", SKIP: "Atla", EDIT_CARD: "Kart\u0131 D\xFCzenle", RESET_CARD_PROGRESS: "Kart\u0131n ilerlemesini s\u0131f\u0131rla", HARD: "Zor", GOOD: "Orta", EASY: "Kolay", SHOW_ANSWER: "Cevab\u0131 G\xF6ster", CARD_PROGRESS_RESET: "Kart\u0131n ilerlemesi s\u0131f\u0131rland\u0131.", SAVE: "Kaydet", CANCEL: "\u0130ptal", NO_INPUT: "Girdi sa\u011Flanmad\u0131.", CURRENT_EASE_HELP_TEXT: "Mevcut Kolayl\u0131k: ", CURRENT_INTERVAL_HELP_TEXT: "Mevcut Aral\u0131k: ", CARD_GENERATED_FROM: "${notePath} kayna\u011F\u0131ndan olu\u015Fturuldu.", // main.ts OPEN_NOTE_FOR_REVIEW: "G\xF6zden ge\xE7irmek i\xE7in bir not a\xE7", REVIEW_CARDS: "Flash kartlar\u0131 g\xF6zden ge\xE7ir", REVIEW_DIFFICULTY_FILE_MENU: "G\xF6zden Ge\xE7ir: ${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "Notu ${difficulty} derecesiyle g\xF6zden ge\xE7ir", CRAM_ALL_CARDS: "T\xFCm destelerden yo\u011Fun tekrar yap", REVIEW_ALL_CARDS: "T\xFCm notlardaki flash kartlar\u0131 g\xF6zden ge\xE7ir", REVIEW_CARDS_IN_NOTE: "Bu nottaki flash kartlar\u0131 g\xF6zden ge\xE7ir", CRAM_CARDS_IN_NOTE: "Bu nottaki flash kartlar\u0131 yo\u011Fun tekrar yap", VIEW_STATS: "\u0130statistikleri g\xF6r\xFCnt\xFCle", OPEN_REVIEW_QUEUE_VIEW: "Kenar \xE7ubu\u011Funda Not G\xF6zden Ge\xE7irme S\u0131ras\u0131n\u0131 a\xE7", STATUS_BAR: "G\xF6zden Ge\xE7ir: ${dueNotesCount} not, ${dueFlashcardsCount} kart g\xFCncel", SYNC_TIME_TAKEN: "Senkronizasyon ${t}ms s\xFCrd\xFC", NOTE_IN_IGNORED_FOLDER: "Not, d\u0131\u015Flanan klas\xF6rde kay\u0131tl\u0131 (ayarlar\u0131 kontrol edin).", PLEASE_TAG_NOTE: "L\xFCtfen g\xF6zden ge\xE7irmek i\xE7in notu uygun \u015Fekilde etiketleyin (ayarlar i\xE7inde).", RESPONSE_RECEIVED: "Yan\u0131t al\u0131nd\u0131.", NO_DECK_EXISTS: "${deckName} ad\u0131nda bir deste yok", ALL_CAUGHT_UP: "\u{1F3C6} \u015Eampiyon gibi bitirdin! \u{1F604}", // scheduling.ts DAYS_STR_IVL: "${interval} g\xFCn", MONTHS_STR_IVL: "${interval} ay", YEARS_STR_IVL: "${interval} y\u0131l", DAYS_STR_IVL_MOBILE: "${interval}g", MONTHS_STR_IVL_MOBILE: "${interval}a", YEARS_STR_IVL_MOBILE: "${interval}y", // settings.ts SETTINGS_HEADER: "Aral\u0131kl\u0131 Tekrar", GROUP_TAGS_FOLDERS: "Etiketler ve Klas\xF6rler", GROUP_FLASHCARD_REVIEW: "Flash Kartlar\u0131 G\xF6zden Ge\xE7irme", GROUP_FLASHCARD_SEPARATORS: "Flash Kart Ay\u0131r\u0131c\u0131lar\u0131", GROUP_DATA_STORAGE: "Planlama Verilerinin Saklanmas\u0131", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flash Kartlar ve Notlar", GROUP_CONTRIBUTING: "Katk\u0131da Bulunma", CHECK_WIKI: 'Daha fazla bilgi i\xE7in wiki sayfas\u0131na g\xF6z at\u0131n.', GITHUB_DISCUSSIONS: 'Soru-cevap, geri bildirim ve genel tart\u0131\u015Fmalar i\xE7in tart\u0131\u015Fmalar b\xF6l\xFCm\xFCne g\xF6z at\u0131n.', GITHUB_ISSUES: 'Bir \xF6zellik iste\u011Finiz ya da hata bildiriminiz varsa buradan bildirin.', GITHUB_SOURCE_CODE: 'Proje kaynak koduna GitHub \xFCzerinden ula\u015Fabilirsiniz.', CODE_CONTRIBUTION_INFO: 'Kod katk\u0131lar\u0131 hakk\u0131nda bilgi al\u0131n.', TRANSLATION_CONTRIBUTION_INFO: 'Eklentiyi kendi dilinize \xE7evirmek hakk\u0131nda bilgi i\xE7in \xE7eviri katk\u0131lar\u0131 sayfas\u0131n\u0131 ziyaret edin.', FOLDERS_TO_IGNORE: "Yoksay\u0131lan Klas\xF6rler", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "Flash Kartlar", FLASHCARD_EASY_LABEL: "Kolay Butonu Metni", FLASHCARD_GOOD_LABEL: "Orta Butonu Metni", FLASHCARD_HARD_LABEL: "Zor Butonu Metni", FLASHCARD_EASY_DESC: '"Kolay" butonunun metnini \xF6zelle\u015Ftirin', FLASHCARD_GOOD_DESC: '"Orta" butonunun metnini \xF6zelle\u015Ftirin', FLASHCARD_HARD_DESC: '"Zor" butonunun metnini \xF6zelle\u015Ftirin', REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "Flash Kart Etiketleri", FLASHCARD_TAGS_DESC: "Etiketleri bo\u015Fluklar veya yeni sat\u0131rlarla ay\u0131rarak girin, \xF6rne\u011Fin: #flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "Klas\xF6rleri destelere ve alt destelere d\xF6n\xFC\u015Ft\xFCr?", CONVERT_FOLDERS_TO_DECKS_DESC: "Bu, yukar\u0131daki Flash Kart etiketleri se\xE7ene\u011Fine bir alternatiftir.", INLINE_SCHEDULING_COMMENTS: "Planlama yorumunu flash kart\u0131n son sat\u0131r\u0131yla ayn\u0131 sat\u0131ra kaydet?", INLINE_SCHEDULING_COMMENTS_DESC: "Bunu a\xE7mak, HTML yorumlar\u0131n\u0131n liste bi\xE7imlendirmesini bozmamas\u0131n\u0131 sa\u011Flar.", BURY_SIBLINGS_TILL_NEXT_DAY: "Karde\u015F kartlar\u0131 bir sonraki g\xFCne kadar gizle?", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "Karde\u015F kartlar, ayn\u0131 kart metninden \xFCretilen kartlard\u0131r (\xF6rne\u011Fin gizlemeler).", SHOW_CARD_CONTEXT: "Kartlarda ba\u011Flam\u0131 g\xF6ster?", SHOW_CARD_CONTEXT_DESC: "\xD6rne\u011Fin: Ba\u015Fl\u0131k > Ba\u015Fl\u0131k 1 > Alt Ba\u015Fl\u0131k > ... > Alt Ba\u015Fl\u0131k", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "Flash Kart Y\xFCkseklik Y\xFCzdesi", CARD_MODAL_SIZE_PERCENT_DESC: "Mobilde veya \xE7ok b\xFCy\xFCk resimleriniz varsa %100 olarak ayarlay\u0131n.", RESET_DEFAULT: "Varsay\u0131lana s\u0131f\u0131rla", CARD_MODAL_WIDTH_PERCENT: "Flash Kart Geni\u015Flik Y\xFCzdesi", RANDOMIZE_CARD_ORDER: "\u0130nceleme s\u0131ras\u0131nda kart s\u0131ras\u0131n\u0131 rastgele yap?", REVIEW_CARD_ORDER_WITHIN_DECK: "\u0130nceleme s\u0131ras\u0131nda bir destede kartlar\u0131n g\xF6r\xFCnt\xFClenme s\u0131ras\u0131", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "S\u0131ral\u0131 olarak (\xF6nce t\xFCm yeni kartlar)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "S\u0131ral\u0131 olarak (\xF6nce t\xFCm g\xFCncel kartlar)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "Rastgele olarak (\xF6nce t\xFCm yeni kartlar)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "Rastgele olarak (\xF6nce t\xFCm g\xFCncel kartlar)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "Rastgele desteden rastgele kart", REVIEW_DECK_ORDER: "\u0130nceleme s\u0131ras\u0131nda destelerin g\xF6r\xFCnt\xFClenme s\u0131ras\u0131", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "S\u0131ral\u0131 olarak (\xD6nceki destedeki t\xFCm kartlar g\xF6zden ge\xE7irildikten sonra)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "Rastgele olarak (\xD6nceki destedeki t\xFCm kartlar g\xF6zden ge\xE7irildikten sonra)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "Rastgele desteden rastgele kart", DISABLE_CLOZE_CARDS: "Gizli kartlar\u0131 devre d\u0131\u015F\u0131 b\u0131rak?", CONVERT_HIGHLIGHTS_TO_CLOZES: "==Vurgulanan== metni gizli kartlara d\xF6n\xFC\u015Ft\xFCr?", CONVERT_BOLD_TEXT_TO_CLOZES: "**Kal\u0131n metni** gizli kartlara d\xF6n\xFC\u015Ft\xFCr?", CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{K\u0131v\u0131rc\u0131k parantezleri}} gizli kartlara d\xF6n\xFC\u015Ft\xFCr?", CLOZE_PATTERNS: "Cloze Patterns", CLOZE_PATTERNS_DESC: 'Enter cloze patterns separated by newlines. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "Sat\u0131r i\xE7i flash kartlar i\xE7in ay\u0131r\u0131c\u0131", FIX_SEPARATORS_MANUALLY_WARNING: "Bunu de\u011Fi\u015Ftirdikten sonra mevcut flash kartlar\u0131n\u0131z\u0131 manuel olarak d\xFCzenlemeniz gerekti\u011Fini unutmay\u0131n.", INLINE_REVERSED_CARDS_SEPARATOR: "Sat\u0131r i\xE7i ters flash kartlar i\xE7in ay\u0131r\u0131c\u0131", MULTILINE_CARDS_SEPARATOR: "\xC7ok sat\u0131rl\u0131 flash kartlar i\xE7in ay\u0131r\u0131c\u0131", MULTILINE_REVERSED_CARDS_SEPARATOR: "\xC7ok sat\u0131rl\u0131 ters flash kartlar i\xE7in ay\u0131r\u0131c\u0131", MULTILINE_CARDS_END_MARKER: "Gizli kartlar ve \xE7ok sat\u0131rl\u0131 flash kartlar\u0131n sonunu belirten karakterler", NOTES: "Notlar", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "Ba\u015Flang\u0131\xE7ta not inceleme panelini etkinle\u015Ftir", TAGS_TO_REVIEW: "G\xF6zden ge\xE7irilecek etiketler", TAGS_TO_REVIEW_DESC: "Etiketleri bo\u015Fluklar veya yeni sat\u0131rlarla ay\u0131rarak girin, \xF6rne\u011Fin: #review #tag2 #tag3.", OPEN_RANDOM_NOTE: "G\xF6zden ge\xE7irmek i\xE7in rastgele bir not a\xE7", OPEN_RANDOM_NOTE_DESC: "Bunu kapatt\u0131\u011F\u0131n\u0131zda, notlar \xF6nem s\u0131ras\u0131na g\xF6re s\u0131ralan\u0131r (PageRank).", AUTO_NEXT_NOTE: "Bir incelemeden sonra otomatik olarak bir sonraki notu a\xE7", MAX_N_DAYS_REVIEW_QUEUE: "Sa\u011F panelde g\xF6sterilecek maksimum g\xFCn say\u0131s\u0131", MIN_ONE_DAY: "G\xFCn say\u0131s\u0131 en az 1 olmal\u0131d\u0131r.", VALID_NUMBER_WARNING: "L\xFCtfen ge\xE7erli bir say\u0131 girin.", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", ENABLE_FILE_MENU_REVIEW_OPTIONS: "Enable the review options in the file menu (e.g. Review: Easy, Good, Hard)", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "If you disable the review options in the file menu, you can review your notes using the plugin commands and, if you defined them, the associated command hotkeys.", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "Deste a\u011Fa\xE7lar\u0131 ba\u015Flang\u0131\xE7ta geni\u015Fletilmi\u015F olarak g\xF6sterilmeli mi", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "Bunu kapat\u0131n, ayn\u0131 dosyada bir\xE7ok desteye ait kartlar\u0131n\u0131z varsa i\xE7 i\xE7e desteleri daraltmak i\xE7in kullan\u0131\u015Fl\u0131d\u0131r.", ALGORITHM: "Algoritma", CHECK_ALGORITHM_WIKI: 'Daha fazla bilgi i\xE7in algoritma uygulamas\u0131na g\xF6z at\u0131n.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "Temel kolayl\u0131k", BASE_EASE_DESC: "minimum = 130, tercihen yakla\u015F\u0131k 250.", BASE_EASE_MIN_WARNING: "Temel kolayl\u0131k en az 130 olmal\u0131d\u0131r.", LAPSE_INTERVAL_CHANGE: "Bir flash kart\u0131/notu zor olarak inceledi\u011Finizde aral\u0131k de\u011Fi\u015Fikli\u011Fi", LAPSE_INTERVAL_CHANGE_DESC: "yeniAral\u0131k = eskiAral\u0131k * aral\u0131kDe\u011Fi\u015Fikli\u011Fi / 100.", EASY_BONUS: "Kolayl\u0131k Bonusu", EASY_BONUS_DESC: "Kolayl\u0131k bonusu, bir flash kart\u0131/notu \u0130yi ve Kolay yan\u0131tlad\u0131\u011F\u0131n\u0131zda aral\u0131klardaki fark\u0131 ayarlaman\u0131za olanak tan\u0131r (minimum = %100).", EASY_BONUS_MIN_WARNING: "Kolayl\u0131k bonusu en az %100 olmal\u0131d\u0131r.", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "Maksimum aral\u0131k (g\xFCn)", MAX_INTERVAL_DESC: "Aral\u0131\u011Fa bir \xFCst s\u0131n\u0131r koyman\u0131za olanak tan\u0131r (varsay\u0131lan = 100 y\u0131l).", MAX_INTERVAL_MIN_WARNING: "Maksimum aral\u0131k en az 1 g\xFCn olmal\u0131d\u0131r.", MAX_LINK_CONTRIB: "Maksimum ba\u011Flant\u0131 katk\u0131s\u0131", MAX_LINK_CONTRIB_DESC: "Ba\u011Flant\u0131l\u0131 notlar\u0131n a\u011F\u0131rl\u0131kl\u0131 kolayl\u0131k de\u011Ferinin ba\u015Flang\u0131\xE7 kolayl\u0131\u011F\u0131na maksimum katk\u0131s\u0131.", LOGGING: "Kay\u0131t tutma", DISPLAY_SCHEDULING_DEBUG_INFO: "Geli\u015Ftirici konsolunda hata ay\u0131klama bilgilerini g\xF6ster", DISPLAY_PARSER_DEBUG_INFO: "Ayr\u0131\u015Ft\u0131r\u0131c\u0131 i\xE7in hata ay\u0131klama bilgilerini geli\u015Ftirici konsolunda g\xF6ster", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "Not \u0130nceleme S\u0131ras\u0131", CLOSE: "Kapat", NEW: "Yeni", YESTERDAY: "D\xFCn", TODAY: "Bug\xFCn", TOMORROW: "Yar\u0131n", // stats-modal.tsx STATS_TITLE: "\u0130statistikler", MONTH: "Ay", QUARTER: "\xC7eyrek", YEAR: "Y\u0131l", LIFETIME: "\xD6m\xFCr Boyu", FORECAST: "Tahmin", FORECAST_DESC: "Gelecekte incelemeye al\u0131nacak kartlar\u0131n say\u0131s\u0131", SCHEDULED: "Planlanm\u0131\u015F", DAYS: "G\xFCnler", NUMBER_OF_CARDS: "Kart Say\u0131s\u0131", REVIEWS_PER_DAY: "Ortalama: ${avg} inceleme/g\xFCn", INTERVALS: "Aral\u0131klar", INTERVALS_DESC: "\u0130ncelemelerin tekrar g\xF6sterilme gecikmeleri", COUNT: "Say\u0131", INTERVALS_SUMMARY: "Ortalama aral\u0131k: ${avg}, En uzun aral\u0131k: ${longest}", EASES: "Kolayl\u0131klar", EASES_SUMMARY: "Ortalama kolayl\u0131k: ${avgEase}", EASE: "Ease", CARD_TYPES: "Kart T\xFCrleri", CARD_TYPES_DESC: "Bu, g\xF6m\xFCl\xFC kartlar\u0131 da i\xE7erir (varsa)", CARD_TYPE_NEW: "Yeni", CARD_TYPE_YOUNG: "Gen\xE7", CARD_TYPE_MATURE: "Olgun", CARD_TYPES_SUMMARY: "Toplam kart: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/uk.ts var uk_default = {}; // src/lang/locale/ur.ts var ur_default = {}; // src/lang/locale/vi.ts var vi_default = {}; // src/lang/locale/zh-cn.ts var zh_cn_default = { // flashcard-modal.tsx DECKS: "\u5361\u7EC4", DUE_CARDS: "\u5230\u671F\u5361\u7247", NEW_CARDS: "\u65B0\u5361\u7247", TOTAL_CARDS: "\u5168\u90E8\u5361\u7247", BACK: "\u8FD4\u56DE", SKIP: "\u7565\u8FC7", EDIT_CARD: "\u7F16\u8F91\u5361\u7247", RESET_CARD_PROGRESS: "\u91CD\u7F6E\u5361\u7247", HARD: "\u8F83\u96BE", GOOD: "\u8BB0\u5F97", EASY: "\u7B80\u5355", SHOW_ANSWER: "\u663E\u793A\u7B54\u6848", CARD_PROGRESS_RESET: "\u5361\u7247\u5DF2\u88AB\u91CD\u7F6E\u3002", SAVE: "\u50A8\u5B58", CANCEL: "\u53D6\u6D88", NO_INPUT: "\u6CA1\u6709\u63D0\u4F9B\u8F93\u5165\u3002", CURRENT_EASE_HELP_TEXT: "\u76EE\u524D\u638C\u63E1\u7A0B\u5EA6\uFF1A", CURRENT_INTERVAL_HELP_TEXT: "\u76EE\u524D\u95F4\u9694\uFF1A", CARD_GENERATED_FROM: "\u751F\u6210\u81EA\uFF1A${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "\u6253\u5F00\u4E00\u4E2A\u7B14\u8BB0\u5F00\u59CB\u590D\u4E60", REVIEW_CARDS: "\u590D\u4E60\u5361\u7247", REVIEW_DIFFICULTY_FILE_MENU: "\u590D\u4E60\uFF1A${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "\u6807\u8BB0\u4E3A\u201C${difficulty}\u201D", REVIEW_ALL_CARDS: "\u590D\u4E60\u6240\u6709\u7B14\u8BB0\u4E2D\u7684\u5361\u7247", CRAM_ALL_CARDS: "\u9009\u62E9\u8981\u96C6\u4E2D\u590D\u4E60\u7684\u5361\u7EC4", REVIEW_CARDS_IN_NOTE: "\u590D\u4E60\u6B64\u7B14\u8BB0\u4E2D\u7684\u5361\u7247", CRAM_CARDS_IN_NOTE: "\u96C6\u4E2D\u590D\u4E60\u6B64\u7B14\u8BB0\u4E2D\u7684\u5361\u7247", VIEW_STATS: "\u67E5\u770B\u6570\u636E", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "\u590D\u4E60: ${dueNotesCount} \u7B14\u8BB0, ${dueFlashcardsCount} \u5361\u7247\u5DF2\u5230\u671F", SYNC_TIME_TAKEN: "\u540C\u6B65\u65F6\u95F4 ${t}ms", NOTE_IN_IGNORED_FOLDER: "\u7B14\u8BB0\u4FDD\u5B58\u5728\u5DF2\u88AB\u5FFD\u7565\u7684\u8DEF\u5F84\u4E2D\uFF08\u68C0\u67E5\u8BBE\u7F6E\u9009\u9879\uFF09\u3002", PLEASE_TAG_NOTE: "\u8BF7\u5C06\u9700\u8981\u590D\u4E60\u7684\u7B14\u8BB0\u4E2D\u52A0\u5165\u6B63\u786E\u7684\u6807\u7B7E\uFF08\u68C0\u67E5\u8BBE\u7F6E\u9009\u9879\uFF09\u3002", RESPONSE_RECEIVED: "\u53CD\u9988\u5DF2\u6536\u5230", NO_DECK_EXISTS: "\u6CA1\u6709 ${deckName} \u5361\u7EC4", ALL_CAUGHT_UP: "\u90FD\u590D\u4E60\u5B8C\u5566\uFF0C\u4F60\u771F\u68D2\uFF01", // scheduling.ts DAYS_STR_IVL: "${interval}\u5929", MONTHS_STR_IVL: "${interval}\u6708", YEARS_STR_IVL: "${interval}\u5E74", DAYS_STR_IVL_MOBILE: "${interval}\u5929", MONTHS_STR_IVL_MOBILE: "${interval}\u6708", YEARS_STR_IVL_MOBILE: "${interval}\u5E74", // settings.ts SETTINGS_HEADER: "\u95F4\u9694\u91CD\u590D\u63D2\u4EF6", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '\u4E86\u89E3\u66F4\u591A, \u8BF7\u70B9\u51FBwiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\u5FFD\u7565\u6B64\u6587\u4EF6\u5939", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\u5361\u7247", FLASHCARD_EASY_LABEL: "\u201C\u7B80\u5355\u201D\u6309\u94AE\u6587\u672C", FLASHCARD_GOOD_LABEL: "\u201C\u8BB0\u5F97\u201D\u6309\u94AE\u6587\u672C", FLASHCARD_HARD_LABEL: "\u201C\u8F83\u96BE\u201D\u6309\u94AE\u6587\u672C", FLASHCARD_EASY_DESC: "\u81EA\u5B9A\u4E49\u201C\u7B80\u5355\u201D\u6309\u94AE\u7684\u6807\u7B7E", FLASHCARD_GOOD_DESC: "\u81EA\u5B9A\u4E49\u201C\u8BB0\u5F97\u201D\u6309\u94AE\u7684\u6807\u7B7E", FLASHCARD_HARD_DESC: "\u81EA\u5B9A\u4E49\u201C\u8F83\u96BE\u201D\u6309\u94AE\u7684\u6807\u7B7E", REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\u5361\u7247\u6807\u7B7E", FLASHCARD_TAGS_DESC: "\u8F93\u5165\u6807\u7B7E\uFF0C\u7528\u7A7A\u683C\u6216\u65B0\u5EFA\u884C\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A#flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "\u662F\u5426\u5C06\u6587\u4EF6\u5939\u5185\u5BB9\u8F6C\u6362\u4E3A\u5361\u7247\u7EC4\u548C\u5B50\u5361\u7247\u7EC4\uFF1F", CONVERT_FOLDERS_TO_DECKS_DESC: "\u6B64\u9009\u9879\u4E3A\u5361\u7247\u6807\u7B7E\u9009\u9879\u7684\u66FF\u4EE3\u9009\u9879\u3002", INLINE_SCHEDULING_COMMENTS: "\u662F\u5426\u5C06\u8BA1\u5212\u91CD\u590D\u65F6\u95F4\u4FDD\u5B58\u5728\u5361\u7247\u6700\u540E\u4E00\u884C\u7684\u540C\u4E00\u884C\uFF1F", INLINE_SCHEDULING_COMMENTS_DESC: "HTML\u6CE8\u91CA\u4E0D\u518D\u7834\u574F\u5217\u8868\u683C\u5F0F", BURY_SIBLINGS_TILL_NEXT_DAY: "\u5C06\u5173\u8054\u5361\u7247\u9690\u85CF\u81F3\u4E0B\u4E00\u5929\uFF1F", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "\u5173\u8054\u5361\u7247\u662F\u6765\u81EA\u540C\u4E00\u5361\u7247\u7684\u4E0D\u540C\u5F62\u5F0F\uFF0C \u4F8B\u5982\uFF1A\u5B8C\u5F62\u586B\u7A7A\u5361\u7247", SHOW_CARD_CONTEXT: "\u5728\u5361\u7247\u4E2D\u663E\u793A\u4E0A\u4E0B\u6587\uFF1F", SHOW_CARD_CONTEXT_DESC: "\u4F8B\u5982\uFF1A\u6807\u9898 > \u526F\u6807\u9898 > \u5C0F\u6807\u9898 > ... > \u5C0F\u6807\u9898", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\u5361\u7247\u9AD8\u5EA6\u767E\u5206\u6BD4", CARD_MODAL_SIZE_PERCENT_DESC: "\u8BF7\u5728\u79FB\u52A8\u7AEF\u4F7F\u7528\u5E76\u9700\u8981\u6D4F\u89C8\u8F83\u5927\u56FE\u7247\u65F6\u8BBE\u4E3A100%", RESET_DEFAULT: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4", CARD_MODAL_WIDTH_PERCENT: "\u5361\u7247\u5BBD\u5EA6\u767E\u5206\u6BD4", RANDOMIZE_CARD_ORDER: "\u590D\u4E60\u65F6\u968F\u673A\u663E\u793A\u5361\u7247\uFF1F", REVIEW_CARD_ORDER_WITHIN_DECK: "\u590D\u4E60\u65F6\u5361\u7247\u7EC4\u5185\u7684\u5361\u7247\u6392\u5E8F", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "\u5361\u7247\u7EC4\u5185\u987A\u5E8F (\u5168\u90E8\u65B0\u5361\u7247\u4F18\u5148)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "\u5361\u7247\u7EC4\u5185\u987A\u5E8F (\u5168\u90E8\u5230\u671F\u5361\u7247\u4F18\u5148)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "\u5361\u7247\u7EC4\u5185\u4E71\u5E8F (\u5168\u90E8\u65B0\u5361\u7247\u4F18\u5148)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "\u5361\u7247\u7EC4\u5185\u4E71\u5E8F (\u5168\u90E8\u5230\u671F\u5361\u7247\u4F18\u5148)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "\u5361\u7247\u7EC4\u53CA\u5361\u7247\u90FD\u4E71\u5E8F", REVIEW_DECK_ORDER: "\u590D\u4E60\u65F6\u5361\u7247\u7EC4\u7684\u6392\u5E8F", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "\u987A\u5E8F (\u5728\u524D\u4E00\u5361\u7247\u7EC4\u5185\u5361\u7247\u90FD\u590D\u4E60\u5B8C\u540E)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "\u4E71\u5E8F (\u5728\u524D\u4E00\u5361\u7247\u7EC4\u5185\u5361\u7247\u90FD\u590D\u4E60\u5B8C\u540E)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "\u5361\u7247\u7EC4\u53CA\u5361\u7247\u90FD\u4E71\u5E8F", DISABLE_CLOZE_CARDS: "\u4E0D\u8FDB\u884C\u5B8C\u5F62\u586B\u7A7A\uFF1F", CONVERT_HIGHLIGHTS_TO_CLOZES: "\u5C06 ==\u9AD8\u4EAE== \u8F6C\u6362\u4E3A\u5B8C\u5F62\u586B\u7A7A\uFF1F", CONVERT_BOLD_TEXT_TO_CLOZES: "\u5C06 **\u7C97\u4F53** \u8F6C\u6362\u4E3A\u5B8C\u5F62\u586B\u7A7A\uFF1F", CONVERT_CURLY_BRACKETS_TO_CLOZES: "\u5C06 {{\u5927\u62EC\u53F7}} \u8F6C\u6362\u4E3A\u5B8C\u5F62\u586B\u7A7A\uFF1F", CLOZE_PATTERNS: "\u5B8C\u5F62\u586B\u7A7A\u6A21\u5F0F", CLOZE_PATTERNS_DESC: '\u8F93\u5165\u4EE5\u6362\u884C\u7B26\u5206\u9694\u7684\u5B8C\u5F62\u586B\u7A7A\u6A21\u5F0F. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\u5355\u884C\u5361\u7247\u7684\u5206\u9694\u7B26", FIX_SEPARATORS_MANUALLY_WARNING: "\u6CE8\u610F\uFF1A\u66F4\u6539\u6B64\u9009\u9879\u540E\u4F60\u5C06\u9700\u8981\u81EA\u884C\u66F4\u6539\u5DF2\u5B58\u5728\u5361\u7247\u7684\u5206\u9694\u7B26\u3002", INLINE_REVERSED_CARDS_SEPARATOR: "\u5355\u884C\u7FFB\u8F6C\u5361\u7247\u7684\u5206\u9694\u7B26", MULTILINE_CARDS_SEPARATOR: "\u591A\u884C\u5361\u7247\u7684\u5206\u9694\u7B26", MULTILINE_REVERSED_CARDS_SEPARATOR: "\u591A\u884C\u7FFB\u8F6C\u5361\u7247\u7684\u5206\u9694\u7B26", MULTILINE_CARDS_END_MARKER: "\u8868\u793A\u586B\u7A7A\u548C\u591A\u884C\u95EA\u5361\u7ED3\u675F\u7684\u5B57\u7B26", NOTES: "\u7B14\u8BB0", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "\u542F\u52A8\u65F6\u5F00\u542F\u7B14\u8BB0\u590D\u4E60\u7A97\u683C", TAGS_TO_REVIEW: "\u590D\u4E60\u6807\u7B7E", TAGS_TO_REVIEW_DESC: "\u8F93\u5165\u6807\u7B7E\uFF0C\u7528\u7A7A\u683C\u6216\u65B0\u5EFA\u884C\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A#review #tag2 #tag3.", OPEN_RANDOM_NOTE: "\u590D\u4E60\u968F\u673A\u7B14\u8BB0", OPEN_RANDOM_NOTE_DESC: "\u5173\u95ED\u6B64\u9009\u9879\uFF0C\u7B14\u8BB0\u5C06\u4EE5\u91CD\u8981\u5EA6(PageRank)\u6392\u5E8F\u3002", AUTO_NEXT_NOTE: "\u590D\u4E60\u540E\u81EA\u52A8\u6253\u5F00\u4E0B\u4E00\u4E2A\u7B14\u8BB0", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\u8BF7\u5728\u6587\u4EF6\u83DC\u5355\u4E2D\u542F\u7528\u590D\u4E60\u9009\u9879\uFF08\u4F8B\u5982\uFF1A\u590D\u4E60\uFF1A\u7B80\u5355\u3001\u826F\u597D\u3001\u56F0\u96BE", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\u5982\u679C\u60A8\u5728\u6587\u4EF6\u83DC\u5355\u4E2D\u7981\u7528\u590D\u4E60\u9009\u9879\uFF0C\u60A8\u53EF\u4EE5\u4F7F\u7528\u63D2\u4EF6\u547D\u4EE4\u6765\u590D\u4E60\u7B14\u8BB0\uFF0C\u5982\u679C\u60A8\u5B9A\u4E49\u4E86\u76F8\u5173\u5FEB\u6377\u952E\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528\u5B83\u4EEC\u3002", MAX_N_DAYS_REVIEW_QUEUE: "\u53F3\u8FB9\u680F\u4E2D\u663E\u793A\u7684\u6700\u5927\u5929\u6570", MIN_ONE_DAY: "\u5929\u6570\u6700\u5C0F\u503C\u4E3A1", VALID_NUMBER_WARNING: "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57\u3002", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\u7532\u677F\u6811\u6700\u521D\u5E94\u663E\u793A\u4E3A\u5C55\u5F00", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "\u5173\u95ED\u6B64\u9009\u9879\u53EF\u6298\u53E0\u540C\u4E00\u5F20\u5361\u7247\u4E2D\u7684\u5D4C\u5957\u724C\u7EC4\u3002\u5982\u679C\u60A8\u7684\u5361\u7247\u5C5E\u4E8E\u540C\u4E00\u6587\u4EF6\u4E2D\u7684\u8BB8\u591A\u5957\u724C\uFF0C\u5219\u5F88\u6709\u7528\u3002", ALGORITHM: "\u7B97\u6CD5", CHECK_ALGORITHM_WIKI: '\u4E86\u89E3\u66F4\u591A, \u8BF7\u70B9\u51FB\u7B97\u6CD5\u5B9E\u73B0.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\u57FA\u7840\u638C\u63E1\u7A0B\u5EA6", BASE_EASE_DESC: "\u6700\u5C0F\u503C130\uFF0C\u63A8\u8350\u503C\u7EA6250.", BASE_EASE_MIN_WARNING: "\u57FA\u7840\u638C\u63E1\u7A0B\u5EA6\u7684\u6700\u5C0F\u503C\u4E3A130\u3002", LAPSE_INTERVAL_CHANGE: "\u5C06\u590D\u4E60\u65F6\u6807\u6CE8\u4E3A\u201C\u8F83\u96BE\u201D\u7684\u5361\u7247\u6216\u7B14\u8BB0\u590D\u4E60\u95F4\u9694\u7F29\u77ED", LAPSE_INTERVAL_CHANGE_DESC: "\u65B0\u590D\u4E60\u95F4\u9694 = \u539F\u590D\u4E60\u95F4\u9694 * \u95F4\u9694\u6539\u53D8\u7CFB\u6570 / 100.", EASY_BONUS: "\u7B80\u5355\u5956\u52B1", EASY_BONUS_DESC: "\u7B80\u5355\u5956\u52B1\u8BBE\u5B9A\u201C\u8BB0\u5F97\u201D\u548C\u201C\u7B80\u5355\u201D\u5361\u7247\u6216\u7B14\u8BB0\u7684\u590D\u4E60\u95F4\u9694\u5DEE\u8DDD\uFF08\u6700\u5C0F\u503C100%\uFF09\u3002", EASY_BONUS_MIN_WARNING: "\u7B80\u5355\u5956\u52B1\u81F3\u5C11\u4E3A100\u3002", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "\u6700\u5927\u95F4\u9694\uFF08\u5929\uFF09", MAX_INTERVAL_DESC: "\u8BBE\u5B9A\u590D\u4E60\u7684\u6700\u5927\u95F4\u9694\u65F6\u95F4\uFF08\u9ED8\u8BA4\u503C100\u5E74\uFF09\u3002", MAX_INTERVAL_MIN_WARNING: "\u6700\u5927\u95F4\u9694\u81F3\u5C11\u4E3A1\u5929", MAX_LINK_CONTRIB: "\u6700\u5927\u94FE\u63A5\u6536\u76CA", MAX_LINK_CONTRIB_DESC: "\u94FE\u63A5\u7B14\u8BB0\u7684\u52A0\u6743\u638C\u63E1\u7A0B\u5EA6\u5BF9\u539F\u59CB\u638C\u63E1\u7A0B\u5EA6\u7684\u6700\u5927\u8D21\u732E\u3002", LOGGING: "\u8BB0\u5F55\u4E2D", DISPLAY_SCHEDULING_DEBUG_INFO: "\u5728\u5F00\u53D1\u8005\u63A7\u5236\u53F0\u4E2D\u663E\u793A\u8C03\u8BD5\u4FE1\u606F", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\u7B14\u8BB0\u590D\u4E60\u5E8F\u5217", CLOSE: "\u4E34\u8FD1", NEW: "\u65B0", YESTERDAY: "\u6628\u5929", TODAY: "\u4ECA\u5929", TOMORROW: "\u660E\u5929", // stats-modal.tsx STATS_TITLE: "\u6570\u636E", MONTH: "\u6708", QUARTER: "\u5B63", YEAR: "\u5E74", LIFETIME: "\u5168\u90E8", FORECAST: "\u9884\u671F", FORECAST_DESC: "\u5C06\u8981\u5230\u671F\u7684\u5361\u7247\u6570\u91CF", SCHEDULED: "\u5DF2\u6392\u671F", DAYS: "\u5929", NUMBER_OF_CARDS: "\u5361\u7247\u6570\u91CF", REVIEWS_PER_DAY: "\u5E73\u5747: \u590D\u4E60${avg} /\u5929", INTERVALS: "\u95F4\u9694", INTERVALS_DESC: "\u5230\u4E0B\u4E00\u6B21\u590D\u4E60\u7684\u65F6\u95F4\u95F4\u9694", COUNT: "\u8BA1\u6570", INTERVALS_SUMMARY: "\u5E73\u5747\u95F4\u9694\u65F6\u95F4: ${avg}, \u6700\u957F\u95F4\u9694\u65F6\u95F4: ${longest}", EASES: "\u638C\u63E1\u7A0B\u5EA6", EASES_SUMMARY: "\u5E73\u5747\u638C\u63E1\u7A0B\u5EA6: ${avgEase}", EASE: "Ease", CARD_TYPES: "\u5361\u7247\u7C7B\u578B", CARD_TYPES_DESC: "\u5982\u6709\uFF0C\u5C06\u663E\u793A\u9690\u85CF\u7684\u5361\u7247", CARD_TYPE_NEW: "\u65B0", CARD_TYPE_YOUNG: "\u8F83\u65B0", CARD_TYPE_MATURE: "\u719F\u6089", CARD_TYPES_SUMMARY: "\u603B\u5361\u7247\u6570: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/locale/zh-tw.ts var zh_tw_default = { // flashcard-modal.tsx DECKS: "\u724C\u7D44", DUE_CARDS: "\u5230\u671F\u5361\u7247", NEW_CARDS: "\u65B0\u5361\u7247", TOTAL_CARDS: "\u5168\u90E8\u5361\u7247", BACK: "\u8FD4\u56DE", SKIP: "\u7565\u904E", EDIT_CARD: "\u7DE8\u8F2F\u5361\u7247", RESET_CARD_PROGRESS: "\u91CD\u7F6E\u5361\u7247", HARD: "\u8F03\u96E3", GOOD: "\u8A18\u5F97", EASY: "\u7C21\u55AE", SHOW_ANSWER: "\u986F\u793A\u7B54\u6848", CARD_PROGRESS_RESET: "\u5361\u7247\u5DF2\u88AB\u91CD\u7F6E\u3002", SAVE: "\u5132\u5B58", CANCEL: "\u53D6\u6D88", NO_INPUT: "\u6C92\u6709\u63D0\u4F9B\u8F38\u5165\u3002", CURRENT_EASE_HELP_TEXT: "\u76EE\u524D\u638C\u63E1\u7A0B\u5EA6\uFF1A", CURRENT_INTERVAL_HELP_TEXT: "\u76EE\u524D\u9593\u9694\u6642\u9593\uFF1A", CARD_GENERATED_FROM: "\u751F\u6210\u81EA\uFF1A${notePath}", // main.ts OPEN_NOTE_FOR_REVIEW: "\u6253\u958B\u4E00\u500B\u7B46\u8A18\u958B\u59CB\u5FA9\u7FD2", REVIEW_CARDS: "\u5FA9\u7FD2\u5361\u7247", REVIEW_DIFFICULTY_FILE_MENU: "\u5FA9\u7FD2\uFF1A${difficulty}", REVIEW_NOTE_DIFFICULTY_CMD: "\u6A19\u8A18\u70BA\u300C${difficulty}\u300D", REVIEW_CARDS_IN_NOTE: "\u5FA9\u7FD2\u6B64\u7B46\u8A18\u4E2D\u7684\u5361\u7247", CRAM_ALL_CARDS: "\u9078\u64C7\u8981\u4E0D\u8A08\u96E3\u6613\u5EA6\u5FA9\u7FD2\u7684\u724C\u7D44", REVIEW_ALL_CARDS: "\u5FA9\u7FD2\u6240\u6709\u7B46\u8A18\u4E2D\u7684\u5361\u7247", CRAM_CARDS_IN_NOTE: "\u4E0D\u8A08\u96E3\u6613\u5EA6\u5FA9\u7FD2\u6B64\u7B46\u8A18\u4E2D\u7684\u5361\u7247", VIEW_STATS: "\u6AA2\u8996\u6578\u64DA", OPEN_REVIEW_QUEUE_VIEW: "Open Notes Review Queue in sidebar", STATUS_BAR: "\u5FA9\u7FD2: ${dueNotesCount} \u7B46\u8A18, ${dueFlashcardsCount} \u5361\u7247\u5DF2\u5230\u671F", SYNC_TIME_TAKEN: "\u540C\u6B65\u6642\u9593 ${t}ms", NOTE_IN_IGNORED_FOLDER: "\u7B46\u8A18\u5132\u5B58\u5728\u5DF2\u88AB\u5FFD\u7565\u7684\u8DEF\u5F91\u4E2D\uFF08\u6AA2\u67E5\u8A2D\u5B9A\u9078\u9805\uFF09\u3002", PLEASE_TAG_NOTE: "\u8ACB\u5C07\u9700\u8981\u5FA9\u7FD2\u7684\u7B46\u8A18\u4E2D\u52A0\u5165\u6B63\u78BA\u7684\u6A19\u7C64\uFF08\u6AA2\u67E5\u8A2D\u5B9A\u9078\u9805\uFF09\u3002", RESPONSE_RECEIVED: "\u56DE\u994B\u5DF2\u6536\u5230", NO_DECK_EXISTS: "\u6C92\u6709 ${deckName} \u724C\u7D44", ALL_CAUGHT_UP: "\u90FD\u5FA9\u7FD2\u5B8C\u5566\uFF0C\u4F60\u771F\u68D2\uFF01", // scheduling.ts DAYS_STR_IVL: "${interval}\u5929", MONTHS_STR_IVL: "${interval}\u6708", YEARS_STR_IVL: "${interval}\u5E74", DAYS_STR_IVL_MOBILE: "${interval}\u5929", MONTHS_STR_IVL_MOBILE: "${interval}\u6708", YEARS_STR_IVL_MOBILE: "${interval}\u5E74", // settings.ts SETTINGS_HEADER: "\u9593\u9694\u91CD\u8907\u5916\u639B", GROUP_TAGS_FOLDERS: "Tags & Folders", GROUP_FLASHCARD_REVIEW: "Flashcard Review", GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators", GROUP_DATA_STORAGE: "Storage of Scheduling Data", GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data", GROUP_FLASHCARDS_NOTES: "Flashcards & Notes", GROUP_CONTRIBUTING: "Contributing", CHECK_WIKI: '\u77AD\u89E3\u66F4\u591A, \u8ACB\u9EDE\u9078wiki.', GITHUB_DISCUSSIONS: 'Visit the discussions section for Q&A help, feedback, and general discussion.', GITHUB_ISSUES: 'Raise an issue here if you have a feature request or a bug report.', GITHUB_SOURCE_CODE: 'The project\'s source code is available on GitHub.', CODE_CONTRIBUTION_INFO: 'Here\'s how to contribute code to the plugin.', TRANSLATION_CONTRIBUTION_INFO: 'Here\'s how to translate the plugin to another language.', FOLDERS_TO_IGNORE: "\u5FFD\u7565\u6B64\u8CC7\u6599\u593E", FOLDERS_TO_IGNORE_DESC: "Enter folder paths or glob patterns on separate lines e.g. Templates/Scripts or **/*.excalidraw.md. This setting is common to both flashcards and notes.", OBSIDIAN_INTEGRATION: "Integration into Obsidian", FLASHCARDS: "\u5361\u7247", FLASHCARD_EASY_LABEL: "\u7C21\u55AE\u6309\u9215\u6587\u5B57", FLASHCARD_GOOD_LABEL: "\u8A18\u5F97\u6309\u9215\u6587\u5B57", FLASHCARD_HARD_LABEL: "\u8F03\u96E3\u6309\u9215\u6587\u5B57", FLASHCARD_EASY_DESC: "\u81EA\u8A02\u300C\u7C21\u55AE\u300D\u6309\u9215\u7684\u6A19\u7C64", FLASHCARD_GOOD_DESC: "\u81EA\u8A02\u300C\u8A18\u5F97\u300D\u6309\u9215\u7684\u6A19\u7C64", FLASHCARD_HARD_DESC: "\u81EA\u8A02\u300C\u8F03\u96E3\u300D\u6309\u9215\u7684\u6A19\u7C64", REVIEW_BUTTON_DELAY: "Button Press Delay (ms)", REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.", FLASHCARD_TAGS: "\u5361\u7247\u6A19\u7C64", FLASHCARD_TAGS_DESC: "\u8F38\u5165\u6A19\u7C64\uFF08\u7528\u7A7A\u767D\u6216\u63DB\u884C\u5B57\u5143\u5206\u9694\uFF09\uFF0C\u4F8B\u5982\uFF1A#flashcards #deck2 #deck3.", CONVERT_FOLDERS_TO_DECKS: "\u662F\u5426\u5C07\u8CC7\u6599\u593E\u5167\u5BB9\u8F49\u63DB\u70BA\u724C\u7D44\u548C\u5B50\u724C\u7D44\uFF1F", CONVERT_FOLDERS_TO_DECKS_DESC: "\u6B64\u9078\u9805\u70BA\u5361\u7247\u6A19\u7C64\u9078\u9805\u7684\u66FF\u4EE3\u9078\u9805\u3002", INLINE_SCHEDULING_COMMENTS: "\u662F\u5426\u5C07\u8A08\u5283\u91CD\u8907\u6642\u9593\u5132\u5B58\u5728\u5361\u7247\u6700\u5F8C\u4E00\u884C\u7684\u540C\u4E00\u884C\uFF1F", INLINE_SCHEDULING_COMMENTS_DESC: "\u52FE\u9078\u5F8CHTML\u8A3B\u89E3\u4E0D\u6703\u7834\u58DE\u5217\u8868\u683C\u5F0F\u554F\u984C\u3002", BURY_SIBLINGS_TILL_NEXT_DAY: "\u5C07\u53CD\u8F49\u5361\u7247\u96B1\u85CF\u81F3\u4E0B\u4E00\u5929\uFF1F", BURY_SIBLINGS_TILL_NEXT_DAY_DESC: "\u53CD\u8F49\u5361\u7247\u7531\u540C\u4E00\u5361\u7247\u6587\u5B57\u7522\u751F\uFF0C\u4F8B\u5982\uFF1A\u586B\u7A7A\u514B\u6F0F\u5B57", SHOW_CARD_CONTEXT: "\u5728\u5361\u7247\u4E2D\u986F\u793A\u4E0A\u4E0B\u6587\uFF1F", SHOW_CARD_CONTEXT_DESC: "\u4F8B\u5982\uFF1A\u6A19\u984C > \u526F\u6A19\u984C > \u5C0F\u6A19\u984C > ... > \u5C0F\u6A19\u984C", SHOW_INTERVAL_IN_REVIEW_BUTTONS: "Show next review time in the review buttons", SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC: "Useful to know how far in the future your cards are being pushed.", CARD_MODAL_HEIGHT_PERCENT: "\u5361\u7247\u9AD8\u5EA6\u767E\u5206\u6BD4", CARD_MODAL_SIZE_PERCENT_DESC: "\u5728\u79FB\u52D5\u7AEF\u6216\u9700\u8981\u8F03\u5927\u5716\u7247\u6642\u61C9\u8A2D\u5B9A\u70BA100%", RESET_DEFAULT: "\u91CD\u7F6E\u70BA\u9810\u8A2D\u503C", CARD_MODAL_WIDTH_PERCENT: "\u5361\u7247\u5BEC\u5EA6\u767E\u5206\u6BD4", RANDOMIZE_CARD_ORDER: "\u5FA9\u7FD2\u6642\u96A8\u6A5F\u986F\u793A\u5361\u7247\uFF1F", REVIEW_CARD_ORDER_WITHIN_DECK: "\u5FA9\u7FD2\u6642\u724C\u7D44\u5167\u7684\u5361\u7247\u6392\u5E8F", REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL: "\u724C\u7D44\u5167\u9806\u5E8F (\u5168\u90E8\u65B0\u5361\u7247\u512A\u5148)", REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL: "\u724C\u7D44\u5167\u9806\u5E8F (\u5168\u90E8\u5230\u671F\u5361\u7247\u512A\u5148)", REVIEW_CARD_ORDER_NEW_FIRST_RANDOM: "\u724C\u7D44\u5167\u4E82\u5E8F (\u5168\u90E8\u65B0\u5361\u7247\u512A\u5148)", REVIEW_CARD_ORDER_DUE_FIRST_RANDOM: "\u724C\u7D44\u5167\u4E82\u5E8F (\u5168\u90E8\u5230\u671F\u5361\u7247\u512A\u5148)", REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD: "\u724C\u7D44\u53CA\u5361\u7247\u90FD\u4E82\u5E8F", REVIEW_DECK_ORDER: "\u5FA9\u7FD2\u6642\u724C\u7D44\u7684\u6392\u5E8F", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL: "\u9806\u5E8F (\u5728\u524D\u4E00\u724C\u7D44\u5167\u5361\u7247\u90FD\u5FA9\u7FD2\u5B8C\u5F8C)", REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM: "\u4E82\u5E8F (\u5728\u524D\u4E00\u724C\u7D44\u5167\u5361\u7247\u90FD\u5FA9\u7FD2\u5B8C\u5F8C)", REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD: "\u724C\u7D44\u53CA\u5361\u7247\u90FD\u4E82\u5E8F", DISABLE_CLOZE_CARDS: "\u505C\u7528\u586B\u7A7A\u514B\u6F0F\u5B57\u5361\u7247\uFF1F", CONVERT_HIGHLIGHTS_TO_CLOZES: "\u5C07 ==\u9AD8\u4EAE== \u8F49\u63DB\u70BA\u586B\u7A7A\u514B\u6F0F\u5B57\uFF1F", CONVERT_BOLD_TEXT_TO_CLOZES: "\u5C07 **\u7C97\u9AD4** \u8F49\u63DB\u70BA\u586B\u7A7A\u514B\u6F0F\u5B57\uFF1F", CONVERT_CURLY_BRACKETS_TO_CLOZES: "\u5C07 {{\u5927\u62EC\u865F}} \u8F49\u63DB\u70BA\u586B\u7A7A\u514B\u6F0F\u5B57\uFF1F", CLOZE_PATTERNS: "\u586B\u7A7A\u514B\u6F0F\u5B57\u6A21\u5F0F", CLOZE_PATTERNS_DESC: '\u8F38\u5165\u4EE5\u63DB\u884C\u7B26\u5206\u9694\u7684\u586B\u7A7A\u514B\u6F0F\u5B57\u6A21\u5F0F. Check the wiki for guidance.', INLINE_CARDS_SEPARATOR: "\u55AE\u884C\u5361\u7247\u7684\u5206\u9694\u5B57\u5143", FIX_SEPARATORS_MANUALLY_WARNING: "\u6CE8\u610F\uFF1A\u66F4\u6539\u6B64\u9078\u9805\u5F8C\u4F60\u5C07\u9700\u8981\u81EA\u884C\u66F4\u6539\u5DF2\u5B58\u5728\u5361\u7247\u7684\u5206\u9694\u5B57\u5143\u3002", INLINE_REVERSED_CARDS_SEPARATOR: "\u55AE\u884C\u53CD\u8F49\u5361\u7247\u7684\u5206\u9694\u5B57\u5143", MULTILINE_CARDS_SEPARATOR: "\u591A\u884C\u5361\u7247\u7684\u5206\u9694\u5B57\u5143", MULTILINE_REVERSED_CARDS_SEPARATOR: "\u591A\u884C\u7FFB\u8F49\u5361\u7247\u7684\u5206\u9694\u5B57\u5143", MULTILINE_CARDS_END_MARKER: "\u8868\u793A\u586B\u7A7A\u548C\u591A\u884C\u95EA\u5361\u7ED3\u675F\u7684\u5B57\u7B26", NOTES: "\u7B46\u8A18", NOTE: "Note", REVIEW_PANE_ON_STARTUP: "\u555F\u52D5\u6642\u958B\u555F\u7B46\u8A18\u5FA9\u7FD2\u7A97\u683C", TAGS_TO_REVIEW: "\u5FA9\u7FD2\u6A19\u7C64", TAGS_TO_REVIEW_DESC: "\u8F38\u5165\u6A19\u7C64\uFF0C\u7528\u7A7A\u683C\u6216\u63DB\u884C\u5B57\u5143\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A#review #tag2 #tag3.", OPEN_RANDOM_NOTE: "\u5FA9\u7FD2\u96A8\u6A5F\u7B46\u8A18", OPEN_RANDOM_NOTE_DESC: "\u95DC\u9589\u6B64\u9078\u9805\uFF0C\u7B46\u8A18\u5C07\u4EE5\u91CD\u8981\u5EA6(PageRank)\u6392\u5E8F\u3002", AUTO_NEXT_NOTE: "\u5FA9\u7FD2\u5F8C\u81EA\u52D5\u6253\u958B\u4E0B\u4E00\u500B\u7B46\u8A18", ENABLE_FILE_MENU_REVIEW_OPTIONS: "\u8ACB\u5728\u6A94\u6848\u9078\u55AE\u4E2D\u555F\u7528\u6AA2\u8996\u9078\u9805\uFF08\u4F8B\u5982\uFF1A\u6AA2\u8996\uFF1A\u7C21\u55AE\u3001\u8A18\u5F97\u3001\u8F03\u96E3\uFF09", ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC: "\u5982\u679C\u60A8\u5728\u6A94\u6848\u9078\u55AE\u4E2D\u505C\u7528\u6AA2\u8996\u9078\u9805\uFF0C\u60A8\u53EF\u4EE5\u4F7F\u7528\u63D2\u4EF6\u6307\u4EE4\u6AA2\u8996\u7B46\u8A18\uFF0C\u5982\u679C\u6709\u8A2D\u5B9A\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528\u76F8\u95DC\u7684\u5FEB\u6377\u9375\u3002", MAX_N_DAYS_REVIEW_QUEUE: "\u53F3\u908A\u9762\u677F\u986F\u793A\u7684\u6700\u5927\u5929\u6578", MIN_ONE_DAY: "\u5929\u6578\u6700\u5C0F\u503C\u70BA1", VALID_NUMBER_WARNING: "\u8ACB\u8F38\u5165\u6709\u6548\u7684\u6578\u5B57\u3002", UI: "User Interface", SHOW_STATUS_BAR: "Show status bar", SHOW_STATUS_BAR_DESC: "Turn this off to hide the flashcard's review status in Obsidian's status bar", SHOW_RIBBON_ICON: "Show icon in the ribbon bar", SHOW_RIBBON_ICON_DESC: "Turn this off to hide the plugin icon from Obsidian's ribbon bar", INITIALLY_EXPAND_SUBDECKS_IN_TREE: "\u724C\u7D44\u6A39\u6700\u521D\u61C9\u986F\u793A\u70BA\u5C55\u958B", INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC: "\u95DC\u9589\u6B64\u9078\u9805\u53EF\u647A\u758A\u540C\u4E00\u5F35\u5361\u7247\u4E2D\u7684\u5DE2\u72C0\u724C\u7D44\u3002\u5982\u679C\u60A8\u7684\u5361\u7247\u5C6C\u65BC\u540C\u4E00\u6A94\u6848\u4E2D\u7684\u8A31\u591A\u5957\u724C\uFF0C\u5247\u5F88\u6709\u7528\u3002", ALGORITHM: "\u6F14\u7B97\u6CD5", CHECK_ALGORITHM_WIKI: '\u77AD\u89E3\u66F4\u591A, \u8ACB\u9EDE\u9078\u7B97\u6CD5\u5BE6\u73FE.', SM2_OSR_VARIANT: "OSR's variant of SM-2", BASE_EASE: "\u57FA\u790E\u638C\u63E1\u7A0B\u5EA6", BASE_EASE_DESC: "\u6700\u5C0F\u503C130\uFF0C\u63A8\u85A6\u503C\u7D04250.", BASE_EASE_MIN_WARNING: "\u57FA\u790E\u638C\u63E1\u7A0B\u5EA6\u7684\u6700\u5C0F\u503C\u70BA130\u3002", LAPSE_INTERVAL_CHANGE: "\u5C07\u5FA9\u7FD2\u6642\u6A19\u8A3B\u70BA\u300C\u8F03\u96E3\u300D\u7684\u5361\u7247\u6216\u7B46\u8A18\u5FA9\u7FD2\u9593\u9694\u7E2E\u77ED", LAPSE_INTERVAL_CHANGE_DESC: "\u65B0\u5FA9\u7FD2\u9593\u9694 = \u539F\u5FA9\u7FD2\u9593\u9694 * \u9593\u9694\u6539\u8B8A\u4FC2\u6578 / 100.", EASY_BONUS: "\u7C21\u55AE\u734E\u52F5", EASY_BONUS_DESC: "\u7C21\u55AE\u734E\u52F5\u8A2D\u5B9A\u300C\u8A18\u5F97\u300D\u548C\u300C\u7C21\u55AE\u300D\u5361\u7247\u6216\u7B46\u8A18\u7684\u5FA9\u7FD2\u9593\u9694\u5DEE\u8DDD\uFF08\u6700\u5C0F\u503C100%\uFF09\u3002", EASY_BONUS_MIN_WARNING: "\u7C21\u55AE\u734E\u52F5\u81F3\u5C11\u70BA100\u3002", LOAD_BALANCE: "Enable load balancer", LOAD_BALANCE_DESC: `Slightly tweaks the interval so that the number of reviews per day is more consistent. It's like Anki's fuzz but instead of being random, it picks the day with the least amount of reviews. It's turned off for small intervals.`, MAX_INTERVAL: "\u6700\u5927\u9593\u9694\uFF08\u5929\uFF09", MAX_INTERVAL_DESC: "\u8A2D\u5B9A\u5FA9\u7FD2\u7684\u6700\u5927\u9593\u9694\u6642\u9593\uFF08\u9810\u8A2D\u503C100\u5E74\uFF09\u3002", MAX_INTERVAL_MIN_WARNING: "\u6700\u5927\u9593\u9694\u81F3\u5C11\u70BA1\u5929", MAX_LINK_CONTRIB: "\u6700\u5927\u93C8\u63A5\u8CA2\u737B", MAX_LINK_CONTRIB_DESC: "\u93C8\u63A5\u7B46\u8A18\u7684\u52A0\u6B0A\u638C\u63E1\u7A0B\u5EA6\u5C0D\u539F\u59CB\u638C\u63E1\u7A0B\u5EA6\u7684\u6700\u5927\u8CA2\u737B\u3002", LOGGING: "\u8A18\u9304\u4E2D", DISPLAY_SCHEDULING_DEBUG_INFO: "\u5728\u958B\u767C\u8005\u63A7\u5236\u53F0\u4E2D\u986F\u793A\u9664\u932F\u8CC7\u8A0A", DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console", SCHEDULING: "Scheduling", EXPERIMENTAL: "Experimental", HELP: "Help", STORE_IN_NOTES: "In the notes", // sidebar.ts NOTES_REVIEW_QUEUE: "\u7B46\u8A18\u5FA9\u7FD2\u5E8F\u5217", CLOSE: "\u81E8\u8FD1", NEW: "\u65B0", YESTERDAY: "\u6628\u5929", TODAY: "\u4ECA\u5929", TOMORROW: "\u660E\u5929", // stats-modal.tsx STATS_TITLE: "\u7D71\u8A08", MONTH: "\u6708", QUARTER: "\u5B63", YEAR: "\u5E74", LIFETIME: "\u5168\u90E8", FORECAST: "\u9810\u6E2C", FORECAST_DESC: "\u5C07\u8981\u5230\u671F\u7684\u5361\u7247\u6578\u91CF", SCHEDULED: "\u5DF2\u6392\u7A0B", DAYS: "\u5929", NUMBER_OF_CARDS: "\u5361\u7247\u6578\u91CF", REVIEWS_PER_DAY: "\u5E73\u5747: \u5FA9\u7FD2${avg} /\u5929", INTERVALS: "\u9593\u9694", INTERVALS_DESC: "\u5230\u4E0B\u4E00\u6B21\u5FA9\u7FD2\u7684\u6642\u9593\u9593\u9694", COUNT: "\u8A08\u6578", INTERVALS_SUMMARY: "\u5E73\u5747\u9593\u9694\u6642\u9593: ${avg}, \u6700\u9577\u9593\u9694\u6642\u9593: ${longest}", EASES: "\u638C\u63E1\u7A0B\u5EA6", EASES_SUMMARY: "\u5E73\u5747\u638C\u63E1\u7A0B\u5EA6: ${avgEase}", EASE: "Ease", CARD_TYPES: "\u5361\u7247\u578B\u5225", CARD_TYPES_DESC: "\u5982\u6709\uFF0C\u5C07\u986F\u793A\u96B1\u85CF\u7684\u5361\u7247", CARD_TYPE_NEW: "\u65B0", CARD_TYPE_YOUNG: "\u8F03\u65B0", CARD_TYPE_MATURE: "\u719F\u6089", CARD_TYPES_SUMMARY: "\u7E3D\u5361\u7247\u6578: ${totalCardsCount}", SEARCH: "Search", PREVIOUS: "Previous", NEXT: "Next" }; // src/lang/helpers.ts var localeMap = { af: af_default, ar: ar_default, bn: bn_default, cs: cz_default, da: da_default, de: de_default, en: en_default, "en-gb": en_gb_default, es: es_default, fr: fr_default, hi: hi_default, id: id_default, it: it_default, ja: ja_default, ko: ko_default, mr: mr_default, nl: nl_default, nn: no_default, pl: pl_default, pt: pt_default, "pt-br": pt_br_default, ro: ro_default, ru: ru_default, sw: sw_default, ta: ta_default, te: te_default, th: th_default, tr: tr_default, uk: uk_default, ur: ur_default, vi: vi_default, "zh-cn": zh_cn_default, "zh-tw": zh_tw_default }; var locale = localeMap[import_obsidian.moment.locale()]; function interpolate(str, params) { const names2 = Object.keys(params); const vals = Object.values(params); return new Function(...names2, `return \`${str}\`;`)(...vals); } function t(str, params) { if (!locale) { console.error(`SRS error: Locale ${import_obsidian.moment.locale()} not found.`); } const result = locale && locale[str] || en_default[str]; if (params) { return interpolate(result, params); } return result; } // src/algorithms/osr/note-scheduling.ts function osrSchedule(response, originalInterval, ease, delayedBeforeReview, settings, dueDateHistogram) { const delayedBeforeReviewDays = Math.max(0, Math.floor(delayedBeforeReview / TICKS_PER_DAY)); let interval = originalInterval; if (response === 0 /* Easy */) { ease += 20; interval = (interval + delayedBeforeReviewDays) * ease / 100; interval *= settings.easyBonus; } else if (response === 1 /* Good */) { interval = (interval + delayedBeforeReviewDays / 2) * ease / 100; } else if (response === 2 /* Hard */) { ease = Math.max(130, ease - 20); interval = Math.max( 1, (interval + delayedBeforeReviewDays / 4) * settings.lapsesIntervalChange ); } if (settings.loadBalance && dueDateHistogram !== void 0) { interval = Math.round(interval); if (interval > 7) { let fuzz; if (interval <= 21) fuzz = 1; else if (interval <= 180) fuzz = Math.min(3, Math.floor(interval * 0.05)); else fuzz = Math.min(7, Math.floor(interval * 0.025)); interval = dueDateHistogram.findLeastUsedIntervalOverRange(interval, fuzz); } } interval = Math.min(interval, settings.maximumInterval); interval = Math.round(interval * 10) / 10; return { interval, ease }; } function textInterval(interval, isMobile) { if (interval === void 0) { return t("NEW"); } const m2 = Math.round(interval / 3.04375) / 10, y2 = Math.round(interval / 36.525) / 10; if (isMobile) { if (m2 < 1) return t("DAYS_STR_IVL_MOBILE", { interval }); else if (y2 < 1) return t("MONTHS_STR_IVL_MOBILE", { interval: m2 }); else return t("YEARS_STR_IVL_MOBILE", { interval: y2 }); } else { if (m2 < 1) return t("DAYS_STR_IVL", { interval }); else if (y2 < 1) return t("MONTHS_STR_IVL", { interval: m2 }); else return t("YEARS_STR_IVL", { interval: y2 }); } } // src/utils/dates.ts var import_moment = __toESM(require_moment()); function formatDateYYYYMMDD(ticks) { return ticks.format(PREFERRED_DATE_FORMAT); } var LiveDateProvider = class { get now() { return (0, import_moment.default)(); } get today() { return (0, import_moment.default)().startOf("day"); } }; var DateUtil = class { static dateStrToMoment(str) { return (0, import_moment.default)(str, ALLOWED_DATE_FORMATS); } }; var globalDateProvider = new LiveDateProvider(); // src/algorithms/base/rep-item-schedule-info.ts var RepItemScheduleInfo = class { get dueDateAsUnix() { return this.dueDate.valueOf(); } isDue() { return this.dueDate && this.dueDate.isSameOrBefore(globalDateProvider.today); } formatDueDate() { return formatDateYYYYMMDD(this.dueDate); } delayedBeforeReviewDaysInt() { return Math.max(0, Math.floor(this.delayedBeforeReviewTicks / TICKS_PER_DAY)); } }; // src/algorithms/osr/rep-item-schedule-info-osr.ts var _RepItemScheduleInfoOsr = class _RepItemScheduleInfoOsr extends RepItemScheduleInfo { constructor(dueDate, interval, latestEase, delayedBeforeReviewTicks = null) { super(); this.dueDate = dueDate; this.interval = Math.round(interval); this.latestEase = latestEase; this.delayedBeforeReviewTicks = delayedBeforeReviewTicks; if (dueDate && delayedBeforeReviewTicks == null) { this.delayedBeforeReviewTicks = globalDateProvider.today.valueOf() - dueDate.valueOf(); } } formatCardScheduleForHtmlComment() { const dateStr = this.dueDate ? this.formatDueDate() : _RepItemScheduleInfoOsr.dummyDueDateForNewCard; return `!${dateStr},${this.interval},${this.latestEase}`; } static get initialInterval() { return 1; } static getDummyScheduleForNewCard(settings) { return _RepItemScheduleInfoOsr.fromDueDateStr( _RepItemScheduleInfoOsr.dummyDueDateForNewCard, _RepItemScheduleInfoOsr.initialInterval, settings.baseEase ); } static fromDueDateStr(dueDateStr, interval, ease, delayedBeforeReviewTicks = null) { const dueDate = DateUtil.dateStrToMoment(dueDateStr); return new _RepItemScheduleInfoOsr(dueDate, interval, ease, delayedBeforeReviewTicks); } }; // A question can have multiple cards. The schedule info for all sibling cards are formatted together // in a single comment, such as: // // // However, not all sibling cards may have been reviewed. Therefore we need a method of indicating that a particular card // has not been reviewed, and should be considered "new" // This is done by using this magic value for the date _RepItemScheduleInfoOsr.dummyDueDateForNewCard = "2000-01-01"; var RepItemScheduleInfoOsr = _RepItemScheduleInfoOsr; // src/note-ease-list.ts var NoteEaseList = class { constructor(settings) { this.dict = {}; this.settings = settings; } get baseEase() { return this.settings.baseEase; } hasEaseForPath(path3) { return Object.prototype.hasOwnProperty.call(this.dict, path3); } getEaseByPath(path3) { let ease = null; if (this.hasEaseForPath(path3)) { ease = Math.round(this.dict[path3]); } return ease; } setEaseForPath(path3, ease) { this.dict[path3] = ease; } }; // src/algorithms/osr/srs-algorithm-osr.ts var SrsAlgorithmOsr = class _SrsAlgorithmOsr { constructor(settings) { this.settings = settings; this.noteEaseList = new NoteEaseList(settings); } static get initialInterval() { return 1; } noteCalcNewSchedule(notePath, osrNoteGraph, response, dueDateNoteHistogram) { const noteLinkStat = osrNoteGraph.calcNoteLinkStat( notePath, this.noteEaseList ); const linkContribution = this.settings.maxLinkFactor * Math.min(1, Math.log(noteLinkStat.totalLinkCount + 0.5) / Math.log(64)); let ease = (1 - linkContribution) * this.settings.baseEase + (noteLinkStat.totalLinkCount > 0 ? linkContribution * noteLinkStat.linkTotal / noteLinkStat.linkPGTotal : linkContribution * this.settings.baseEase); if (this.noteEaseList.hasEaseForPath(notePath)) { ease = (ease + this.noteEaseList.getEaseByPath(notePath)) / 2; } const dueDate = null; const interval = _SrsAlgorithmOsr.initialInterval; ease = Math.round(ease); const temp = new RepItemScheduleInfoOsr(dueDate, interval, ease); const result = this.calcSchedule( temp, response, dueDateNoteHistogram ); result.dueDate = (0, import_moment2.default)(globalDateProvider.today.add(result.interval, "d")); return result; } noteOnLoadedNote(path3, note, noteEase) { let flashcardsInNoteAvgEase = null; if (note) { flashcardsInNoteAvgEase = _SrsAlgorithmOsr.calculateFlashcardAvgEase( note.questionList, this.settings ); } let ease = null; if (flashcardsInNoteAvgEase && noteEase) { ease = (flashcardsInNoteAvgEase + noteEase) / 2; } else { ease = flashcardsInNoteAvgEase ? flashcardsInNoteAvgEase : noteEase; } if (ease) { this.noteEaseList.setEaseForPath(path3, ease); } } static calculateFlashcardAvgEase(questionList, settings) { let totalEase = 0; let scheduledCount = 0; questionList.forEach((question) => { question.cards.filter((card) => card.hasSchedule).forEach((card) => { totalEase += card.scheduleInfo.latestEase; scheduledCount++; }); }); let result = 0; if (scheduledCount > 0) { const flashcardsInNoteAvgEase = totalEase / scheduledCount; const flashcardContribution = Math.min( 1, Math.log(scheduledCount + 0.5) / Math.log(64) ); result = flashcardsInNoteAvgEase * flashcardContribution + settings.baseEase * (1 - flashcardContribution); } return result; } noteCalcUpdatedSchedule(notePath, noteSchedule, response, dueDateNoteHistogram) { const noteScheduleOsr = noteSchedule; const temp = this.calcSchedule( noteScheduleOsr, response, dueDateNoteHistogram ); const interval = temp.interval; const ease = temp.latestEase; const dueDate = (0, import_moment2.default)(globalDateProvider.today.add(interval, "d")); this.noteEaseList.setEaseForPath(notePath, ease); return new RepItemScheduleInfoOsr(dueDate, interval, ease); } calcSchedule(schedule, response, dueDateHistogram) { const temp = osrSchedule( response, schedule.interval, schedule.latestEase, schedule.delayedBeforeReviewTicks, this.settings, dueDateHistogram ); return new RepItemScheduleInfoOsr(globalDateProvider.today, temp.interval, temp.ease); } cardGetResetSchedule() { const interval = _SrsAlgorithmOsr.initialInterval; const ease = this.settings.baseEase; const dueDate = globalDateProvider.today.add(interval, "d"); return new RepItemScheduleInfoOsr(dueDate, interval, ease); } cardGetNewSchedule(response, notePath, dueDateFlashcardHistogram) { let initialEase = this.settings.baseEase; if (this.noteEaseList.hasEaseForPath(notePath)) { initialEase = Math.round(this.noteEaseList.getEaseByPath(notePath)); } const delayBeforeReview = 0; const schedObj = osrSchedule( response, _SrsAlgorithmOsr.initialInterval, initialEase, delayBeforeReview, this.settings, dueDateFlashcardHistogram ); const interval = schedObj.interval; const ease = schedObj.ease; const dueDate = globalDateProvider.today.add(interval, "d"); return new RepItemScheduleInfoOsr(dueDate, interval, ease, delayBeforeReview); } cardCalcUpdatedSchedule(response, cardSchedule, dueDateFlashcardHistogram) { const cardScheduleOsr = cardSchedule; const schedObj = osrSchedule( response, cardScheduleOsr.interval, cardSchedule.latestEase, cardSchedule.delayedBeforeReviewTicks, this.settings, dueDateFlashcardHistogram ); const interval = schedObj.interval; const ease = schedObj.ease; const dueDate = globalDateProvider.today.add(interval, "d"); const delayBeforeReview = 0; return new RepItemScheduleInfoOsr(dueDate, interval, ease, delayBeforeReview); } noteStats() { return this.noteEaseList; } }; // src/algorithms/osr/osr-note-graph.ts var graph = __toESM(require_lib()); // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/index.js var import_brace_expansion = __toESM(require_brace_expansion(), 1); // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/assert-valid-pattern.js var MAX_PATTERN_LENGTH = 1024 * 64; var assertValidPattern = (pattern) => { if (typeof pattern !== "string") { throw new TypeError("invalid pattern"); } if (pattern.length > MAX_PATTERN_LENGTH) { throw new TypeError("pattern is too long"); } }; // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/brace-expressions.js var posixClasses = { "[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true], "[:alpha:]": ["\\p{L}\\p{Nl}", true], "[:ascii:]": ["\\x00-\\x7f", false], "[:blank:]": ["\\p{Zs}\\t", true], "[:cntrl:]": ["\\p{Cc}", true], "[:digit:]": ["\\p{Nd}", true], "[:graph:]": ["\\p{Z}\\p{C}", true, true], "[:lower:]": ["\\p{Ll}", true], "[:print:]": ["\\p{C}", true], "[:punct:]": ["\\p{P}", true], "[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", true], "[:upper:]": ["\\p{Lu}", true], "[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", true], "[:xdigit:]": ["A-Fa-f0-9", false] }; var braceEscape = (s2) => s2.replace(/[[\]\\-]/g, "\\$&"); var regexpEscape = (s2) => s2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); var rangesToString = (ranges) => ranges.join(""); var parseClass = (glob, position) => { const pos = position; if (glob.charAt(pos) !== "[") { throw new Error("not in a brace expression"); } const ranges = []; const negs = []; let i2 = pos + 1; let sawStart = false; let uflag = false; let escaping = false; let negate = false; let endPos = pos; let rangeStart = ""; WHILE: while (i2 < glob.length) { const c2 = glob.charAt(i2); if ((c2 === "!" || c2 === "^") && i2 === pos + 1) { negate = true; i2++; continue; } if (c2 === "]" && sawStart && !escaping) { endPos = i2 + 1; break; } sawStart = true; if (c2 === "\\") { if (!escaping) { escaping = true; i2++; continue; } } if (c2 === "[" && !escaping) { for (const [cls, [unip, u2, neg]] of Object.entries(posixClasses)) { if (glob.startsWith(cls, i2)) { if (rangeStart) { return ["$.", false, glob.length - pos, true]; } i2 += cls.length; if (neg) negs.push(unip); else ranges.push(unip); uflag = uflag || u2; continue WHILE; } } } escaping = false; if (rangeStart) { if (c2 > rangeStart) { ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c2)); } else if (c2 === rangeStart) { ranges.push(braceEscape(c2)); } rangeStart = ""; i2++; continue; } if (glob.startsWith("-]", i2 + 1)) { ranges.push(braceEscape(c2 + "-")); i2 += 2; continue; } if (glob.startsWith("-", i2 + 1)) { rangeStart = c2; i2 += 2; continue; } ranges.push(braceEscape(c2)); i2++; } if (endPos < i2) { return ["", false, 0, false]; } if (!ranges.length && !negs.length) { return ["$.", false, glob.length - pos, true]; } if (negs.length === 0 && ranges.length === 1 && /^\\?.$/.test(ranges[0]) && !negate) { const r2 = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]; return [regexpEscape(r2), false, endPos - pos, false]; } const sranges = "[" + (negate ? "^" : "") + rangesToString(ranges) + "]"; const snegs = "[" + (negate ? "" : "^") + rangesToString(negs) + "]"; const comb = ranges.length && negs.length ? "(" + sranges + "|" + snegs + ")" : ranges.length ? sranges : snegs; return [comb, uflag, endPos - pos, true]; }; // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/unescape.js var unescape = (s2, { windowsPathsNoEscape = false } = {}) => { return windowsPathsNoEscape ? s2.replace(/\[([^\/\\])\]/g, "$1") : s2.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1"); }; // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/ast.js var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]); var isExtglobType = (c2) => types.has(c2); var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))"; var startNoDot = "(?!\\.)"; var addPatternStart = /* @__PURE__ */ new Set(["[", "."]); var justDots = /* @__PURE__ */ new Set(["..", "."]); var reSpecials = new Set("().*{}+?[]^$\\!"); var regExpEscape = (s2) => s2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); var qmark = "[^/]"; var star = qmark + "*?"; var starNoEmpty = qmark + "+?"; var _root, _hasMagic, _uflag, _parts, _parent, _parentIndex, _negs, _filledNegs, _options, _toString, _emptyExt, _AST_instances, fillNegs_fn, _AST_static, parseAST_fn, partsToRegExp_fn, parseGlob_fn; var _AST = class _AST { constructor(type, parent, options = {}) { __privateAdd(this, _AST_instances); __publicField(this, "type"); __privateAdd(this, _root); __privateAdd(this, _hasMagic); __privateAdd(this, _uflag, false); __privateAdd(this, _parts, []); __privateAdd(this, _parent); __privateAdd(this, _parentIndex); __privateAdd(this, _negs); __privateAdd(this, _filledNegs, false); __privateAdd(this, _options); __privateAdd(this, _toString); // set to true if it's an extglob with no children // (which really means one child of '') __privateAdd(this, _emptyExt, false); this.type = type; if (type) __privateSet(this, _hasMagic, true); __privateSet(this, _parent, parent); __privateSet(this, _root, __privateGet(this, _parent) ? __privateGet(__privateGet(this, _parent), _root) : this); __privateSet(this, _options, __privateGet(this, _root) === this ? options : __privateGet(__privateGet(this, _root), _options)); __privateSet(this, _negs, __privateGet(this, _root) === this ? [] : __privateGet(__privateGet(this, _root), _negs)); if (type === "!" && !__privateGet(__privateGet(this, _root), _filledNegs)) __privateGet(this, _negs).push(this); __privateSet(this, _parentIndex, __privateGet(this, _parent) ? __privateGet(__privateGet(this, _parent), _parts).length : 0); } get hasMagic() { if (__privateGet(this, _hasMagic) !== void 0) return __privateGet(this, _hasMagic); for (const p2 of __privateGet(this, _parts)) { if (typeof p2 === "string") continue; if (p2.type || p2.hasMagic) return __privateSet(this, _hasMagic, true); } return __privateGet(this, _hasMagic); } // reconstructs the pattern toString() { if (__privateGet(this, _toString) !== void 0) return __privateGet(this, _toString); if (!this.type) { return __privateSet(this, _toString, __privateGet(this, _parts).map((p2) => String(p2)).join("")); } else { return __privateSet(this, _toString, this.type + "(" + __privateGet(this, _parts).map((p2) => String(p2)).join("|") + ")"); } } push(...parts) { for (const p2 of parts) { if (p2 === "") continue; if (typeof p2 !== "string" && !(p2 instanceof _AST && __privateGet(p2, _parent) === this)) { throw new Error("invalid part: " + p2); } __privateGet(this, _parts).push(p2); } } toJSON() { var _a; const ret = this.type === null ? __privateGet(this, _parts).slice().map((p2) => typeof p2 === "string" ? p2 : p2.toJSON()) : [this.type, ...__privateGet(this, _parts).map((p2) => p2.toJSON())]; if (this.isStart() && !this.type) ret.unshift([]); if (this.isEnd() && (this === __privateGet(this, _root) || __privateGet(__privateGet(this, _root), _filledNegs) && ((_a = __privateGet(this, _parent)) == null ? void 0 : _a.type) === "!")) { ret.push({}); } return ret; } isStart() { var _a; if (__privateGet(this, _root) === this) return true; if (!((_a = __privateGet(this, _parent)) == null ? void 0 : _a.isStart())) return false; if (__privateGet(this, _parentIndex) === 0) return true; const p2 = __privateGet(this, _parent); for (let i2 = 0; i2 < __privateGet(this, _parentIndex); i2++) { const pp = __privateGet(p2, _parts)[i2]; if (!(pp instanceof _AST && pp.type === "!")) { return false; } } return true; } isEnd() { var _a, _b, _c; if (__privateGet(this, _root) === this) return true; if (((_a = __privateGet(this, _parent)) == null ? void 0 : _a.type) === "!") return true; if (!((_b = __privateGet(this, _parent)) == null ? void 0 : _b.isEnd())) return false; if (!this.type) return (_c = __privateGet(this, _parent)) == null ? void 0 : _c.isEnd(); const pl = __privateGet(this, _parent) ? __privateGet(__privateGet(this, _parent), _parts).length : 0; return __privateGet(this, _parentIndex) === pl - 1; } copyIn(part) { if (typeof part === "string") this.push(part); else this.push(part.clone(this)); } clone(parent) { const c2 = new _AST(this.type, parent); for (const p2 of __privateGet(this, _parts)) { c2.copyIn(p2); } return c2; } static fromGlob(pattern, options = {}) { var _a; const ast = new _AST(null, void 0, options); __privateMethod(_a = _AST, _AST_static, parseAST_fn).call(_a, pattern, ast, 0, options); return ast; } // returns the regular expression if there's magic, or the unescaped // string if not. toMMPattern() { if (this !== __privateGet(this, _root)) return __privateGet(this, _root).toMMPattern(); const glob = this.toString(); const [re, body, hasMagic, uflag] = this.toRegExpSource(); const anyMagic = hasMagic || __privateGet(this, _hasMagic) || __privateGet(this, _options).nocase && !__privateGet(this, _options).nocaseMagicOnly && glob.toUpperCase() !== glob.toLowerCase(); if (!anyMagic) { return body; } const flags = (__privateGet(this, _options).nocase ? "i" : "") + (uflag ? "u" : ""); return Object.assign(new RegExp(`^${re}$`, flags), { _src: re, _glob: glob }); } get options() { return __privateGet(this, _options); } // returns the string match, the regexp source, whether there's magic // in the regexp (so a regular expression is required) and whether or // not the uflag is needed for the regular expression (for posix classes) // TODO: instead of injecting the start/end at this point, just return // the BODY of the regexp, along with the start/end portions suitable // for binding the start/end in either a joined full-path makeRe context // (where we bind to (^|/), or a standalone matchPart context (where // we bind to ^, and not /). Otherwise slashes get duped! // // In part-matching mode, the start is: // - if not isStart: nothing // - if traversal possible, but not allowed: ^(?!\.\.?$) // - if dots allowed or not possible: ^ // - if dots possible and not allowed: ^(?!\.) // end is: // - if not isEnd(): nothing // - else: $ // // In full-path matching mode, we put the slash at the START of the // pattern, so start is: // - if first pattern: same as part-matching mode // - if not isStart(): nothing // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) // - if dots allowed or not possible: / // - if dots possible and not allowed: /(?!\.) // end is: // - if last pattern, same as part-matching mode // - else nothing // // Always put the (?:$|/) on negated tails, though, because that has to be // there to bind the end of the negated pattern portion, and it's easier to // just stick it in now rather than try to inject it later in the middle of // the pattern. // // We can just always return the same end, and leave it up to the caller // to know whether it's going to be used joined or in parts. // And, if the start is adjusted slightly, can do the same there: // - if not isStart: nothing // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) // - if dots allowed or not possible: (?:/|^) // - if dots possible and not allowed: (?:/|^)(?!\.) // // But it's better to have a simpler binding without a conditional, for // performance, so probably better to return both start options. // // Then the caller just ignores the end if it's not the first pattern, // and the start always gets applied. // // But that's always going to be $ if it's the ending pattern, or nothing, // so the caller can just attach $ at the end of the pattern when building. // // So the todo is: // - better detect what kind of start is needed // - return both flavors of starting pattern // - attach $ at the end of the pattern when creating the actual RegExp // // Ah, but wait, no, that all only applies to the root when the first pattern // is not an extglob. If the first pattern IS an extglob, then we need all // that dot prevention biz to live in the extglob portions, because eg // +(*|.x*) can match .xy but not .yx. // // So, return the two flavors if it's #root and the first child is not an // AST, otherwise leave it to the child AST to handle it, and there, // use the (?:^|/) style of start binding. // // Even simplified further: // - Since the start for a join is eg /(?!\.) and the start for a part // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root // or start or whatever) and prepend ^ or / at the Regexp construction. toRegExpSource(allowDot) { var _a; const dot = allowDot != null ? allowDot : !!__privateGet(this, _options).dot; if (__privateGet(this, _root) === this) __privateMethod(this, _AST_instances, fillNegs_fn).call(this); if (!this.type) { const noEmpty = this.isStart() && this.isEnd(); const src = __privateGet(this, _parts).map((p2) => { var _a2; const [re, _2, hasMagic, uflag] = typeof p2 === "string" ? __privateMethod(_a2 = _AST, _AST_static, parseGlob_fn).call(_a2, p2, __privateGet(this, _hasMagic), noEmpty) : p2.toRegExpSource(allowDot); __privateSet(this, _hasMagic, __privateGet(this, _hasMagic) || hasMagic); __privateSet(this, _uflag, __privateGet(this, _uflag) || uflag); return re; }).join(""); let start2 = ""; if (this.isStart()) { if (typeof __privateGet(this, _parts)[0] === "string") { const dotTravAllowed = __privateGet(this, _parts).length === 1 && justDots.has(__privateGet(this, _parts)[0]); if (!dotTravAllowed) { const aps = addPatternStart; const needNoTrav = ( // dots are allowed, and the pattern starts with [ or . dot && aps.has(src.charAt(0)) || // the pattern starts with \., and then [ or . src.startsWith("\\.") && aps.has(src.charAt(2)) || // the pattern starts with \.\., and then [ or . src.startsWith("\\.\\.") && aps.has(src.charAt(4)) ); const needNoDot = !dot && !allowDot && aps.has(src.charAt(0)); start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ""; } } } let end = ""; if (this.isEnd() && __privateGet(__privateGet(this, _root), _filledNegs) && ((_a = __privateGet(this, _parent)) == null ? void 0 : _a.type) === "!") { end = "(?:$|\\/)"; } const final2 = start2 + src + end; return [ final2, unescape(src), __privateSet(this, _hasMagic, !!__privateGet(this, _hasMagic)), __privateGet(this, _uflag) ]; } const repeated = this.type === "*" || this.type === "+"; const start = this.type === "!" ? "(?:(?!(?:" : "(?:"; let body = __privateMethod(this, _AST_instances, partsToRegExp_fn).call(this, dot); if (this.isStart() && this.isEnd() && !body && this.type !== "!") { const s2 = this.toString(); __privateSet(this, _parts, [s2]); this.type = null; __privateSet(this, _hasMagic, void 0); return [s2, unescape(this.toString()), false, false]; } let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : __privateMethod(this, _AST_instances, partsToRegExp_fn).call(this, true); if (bodyDotAllowed === body) { bodyDotAllowed = ""; } if (bodyDotAllowed) { body = `(?:${body})(?:${bodyDotAllowed})*?`; } let final = ""; if (this.type === "!" && __privateGet(this, _emptyExt)) { final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty; } else { const close = this.type === "!" ? ( // !() must match something,but !(x) can match '' "))" + (this.isStart() && !dot && !allowDot ? startNoDot : "") + star + ")" ) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && bodyDotAllowed ? ")" : this.type === "*" && bodyDotAllowed ? `)?` : `)${this.type}`; final = start + body + close; } return [ final, unescape(body), __privateSet(this, _hasMagic, !!__privateGet(this, _hasMagic)), __privateGet(this, _uflag) ]; } }; _root = new WeakMap(); _hasMagic = new WeakMap(); _uflag = new WeakMap(); _parts = new WeakMap(); _parent = new WeakMap(); _parentIndex = new WeakMap(); _negs = new WeakMap(); _filledNegs = new WeakMap(); _options = new WeakMap(); _toString = new WeakMap(); _emptyExt = new WeakMap(); _AST_instances = new WeakSet(); fillNegs_fn = function() { if (this !== __privateGet(this, _root)) throw new Error("should only call on root"); if (__privateGet(this, _filledNegs)) return this; this.toString(); __privateSet(this, _filledNegs, true); let n2; while (n2 = __privateGet(this, _negs).pop()) { if (n2.type !== "!") continue; let p2 = n2; let pp = __privateGet(p2, _parent); while (pp) { for (let i2 = __privateGet(p2, _parentIndex) + 1; !pp.type && i2 < __privateGet(pp, _parts).length; i2++) { for (const part of __privateGet(n2, _parts)) { if (typeof part === "string") { throw new Error("string part in extglob AST??"); } part.copyIn(__privateGet(pp, _parts)[i2]); } } p2 = pp; pp = __privateGet(p2, _parent); } } return this; }; _AST_static = new WeakSet(); parseAST_fn = function(str, ast, pos, opt) { var _a, _b; let escaping = false; let inBrace = false; let braceStart = -1; let braceNeg = false; if (ast.type === null) { let i3 = pos; let acc2 = ""; while (i3 < str.length) { const c2 = str.charAt(i3++); if (escaping || c2 === "\\") { escaping = !escaping; acc2 += c2; continue; } if (inBrace) { if (i3 === braceStart + 1) { if (c2 === "^" || c2 === "!") { braceNeg = true; } } else if (c2 === "]" && !(i3 === braceStart + 2 && braceNeg)) { inBrace = false; } acc2 += c2; continue; } else if (c2 === "[") { inBrace = true; braceStart = i3; braceNeg = false; acc2 += c2; continue; } if (!opt.noext && isExtglobType(c2) && str.charAt(i3) === "(") { ast.push(acc2); acc2 = ""; const ext2 = new _AST(c2, ast); i3 = __privateMethod(_a = _AST, _AST_static, parseAST_fn).call(_a, str, ext2, i3, opt); ast.push(ext2); continue; } acc2 += c2; } ast.push(acc2); return i3; } let i2 = pos + 1; let part = new _AST(null, ast); const parts = []; let acc = ""; while (i2 < str.length) { const c2 = str.charAt(i2++); if (escaping || c2 === "\\") { escaping = !escaping; acc += c2; continue; } if (inBrace) { if (i2 === braceStart + 1) { if (c2 === "^" || c2 === "!") { braceNeg = true; } } else if (c2 === "]" && !(i2 === braceStart + 2 && braceNeg)) { inBrace = false; } acc += c2; continue; } else if (c2 === "[") { inBrace = true; braceStart = i2; braceNeg = false; acc += c2; continue; } if (isExtglobType(c2) && str.charAt(i2) === "(") { part.push(acc); acc = ""; const ext2 = new _AST(c2, part); part.push(ext2); i2 = __privateMethod(_b = _AST, _AST_static, parseAST_fn).call(_b, str, ext2, i2, opt); continue; } if (c2 === "|") { part.push(acc); acc = ""; parts.push(part); part = new _AST(null, ast); continue; } if (c2 === ")") { if (acc === "" && __privateGet(ast, _parts).length === 0) { __privateSet(ast, _emptyExt, true); } part.push(acc); acc = ""; ast.push(...parts, part); return i2; } acc += c2; } ast.type = null; __privateSet(ast, _hasMagic, void 0); __privateSet(ast, _parts, [str.substring(pos - 1)]); return i2; }; partsToRegExp_fn = function(dot) { return __privateGet(this, _parts).map((p2) => { if (typeof p2 === "string") { throw new Error("string type in extglob ast??"); } const [re, _2, _hasMagic2, uflag] = p2.toRegExpSource(dot); __privateSet(this, _uflag, __privateGet(this, _uflag) || uflag); return re; }).filter((p2) => !(this.isStart() && this.isEnd()) || !!p2).join("|"); }; parseGlob_fn = function(glob, hasMagic, noEmpty = false) { let escaping = false; let re = ""; let uflag = false; for (let i2 = 0; i2 < glob.length; i2++) { const c2 = glob.charAt(i2); if (escaping) { escaping = false; re += (reSpecials.has(c2) ? "\\" : "") + c2; continue; } if (c2 === "\\") { if (i2 === glob.length - 1) { re += "\\\\"; } else { escaping = true; } continue; } if (c2 === "[") { const [src, needUflag, consumed, magic] = parseClass(glob, i2); if (consumed) { re += src; uflag = uflag || needUflag; i2 += consumed - 1; hasMagic = hasMagic || magic; continue; } } if (c2 === "*") { if (noEmpty && glob === "*") re += starNoEmpty; else re += star; hasMagic = true; continue; } if (c2 === "?") { re += qmark; hasMagic = true; continue; } re += regExpEscape(c2); } return [re, unescape(glob), !!hasMagic, uflag]; }; __privateAdd(_AST, _AST_static); var AST = _AST; // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/escape.js var escape = (s2, { windowsPathsNoEscape = false } = {}) => { return windowsPathsNoEscape ? s2.replace(/[?*()[\]]/g, "[$&]") : s2.replace(/[?*()[\]\\]/g, "\\$&"); }; // node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/index.js var minimatch = (p2, pattern, options = {}) => { assertValidPattern(pattern); if (!options.nocomment && pattern.charAt(0) === "#") { return false; } return new Minimatch(pattern, options).match(p2); }; var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; var starDotExtTest = (ext2) => (f2) => !f2.startsWith(".") && f2.endsWith(ext2); var starDotExtTestDot = (ext2) => (f2) => f2.endsWith(ext2); var starDotExtTestNocase = (ext2) => { ext2 = ext2.toLowerCase(); return (f2) => !f2.startsWith(".") && f2.toLowerCase().endsWith(ext2); }; var starDotExtTestNocaseDot = (ext2) => { ext2 = ext2.toLowerCase(); return (f2) => f2.toLowerCase().endsWith(ext2); }; var starDotStarRE = /^\*+\.\*+$/; var starDotStarTest = (f2) => !f2.startsWith(".") && f2.includes("."); var starDotStarTestDot = (f2) => f2 !== "." && f2 !== ".." && f2.includes("."); var dotStarRE = /^\.\*+$/; var dotStarTest = (f2) => f2 !== "." && f2 !== ".." && f2.startsWith("."); var starRE = /^\*+$/; var starTest = (f2) => f2.length !== 0 && !f2.startsWith("."); var starTestDot = (f2) => f2.length !== 0 && f2 !== "." && f2 !== ".."; var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; var qmarksTestNocase = ([$0, ext2 = ""]) => { const noext = qmarksTestNoExt([$0]); if (!ext2) return noext; ext2 = ext2.toLowerCase(); return (f2) => noext(f2) && f2.toLowerCase().endsWith(ext2); }; var qmarksTestNocaseDot = ([$0, ext2 = ""]) => { const noext = qmarksTestNoExtDot([$0]); if (!ext2) return noext; ext2 = ext2.toLowerCase(); return (f2) => noext(f2) && f2.toLowerCase().endsWith(ext2); }; var qmarksTestDot = ([$0, ext2 = ""]) => { const noext = qmarksTestNoExtDot([$0]); return !ext2 ? noext : (f2) => noext(f2) && f2.endsWith(ext2); }; var qmarksTest = ([$0, ext2 = ""]) => { const noext = qmarksTestNoExt([$0]); return !ext2 ? noext : (f2) => noext(f2) && f2.endsWith(ext2); }; var qmarksTestNoExt = ([$0]) => { const len = $0.length; return (f2) => f2.length === len && !f2.startsWith("."); }; var qmarksTestNoExtDot = ([$0]) => { const len = $0.length; return (f2) => f2.length === len && f2 !== "." && f2 !== ".."; }; var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix"; var path = { win32: { sep: "\\" }, posix: { sep: "/" } }; var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep; minimatch.sep = sep; var GLOBSTAR = Symbol("globstar **"); minimatch.GLOBSTAR = GLOBSTAR; var qmark2 = "[^/]"; var star2 = qmark2 + "*?"; var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?"; var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?"; var filter = (pattern, options = {}) => (p2) => minimatch(p2, pattern, options); minimatch.filter = filter; var ext = (a2, b2 = {}) => Object.assign({}, a2, b2); var defaults = (def) => { if (!def || typeof def !== "object" || !Object.keys(def).length) { return minimatch; } const orig = minimatch; const m2 = (p2, pattern, options = {}) => orig(p2, pattern, ext(def, options)); return Object.assign(m2, { Minimatch: class Minimatch extends orig.Minimatch { constructor(pattern, options = {}) { super(pattern, ext(def, options)); } static defaults(options) { return orig.defaults(ext(def, options)).Minimatch; } }, AST: class AST extends orig.AST { /* c8 ignore start */ constructor(type, parent, options = {}) { super(type, parent, ext(def, options)); } /* c8 ignore stop */ static fromGlob(pattern, options = {}) { return orig.AST.fromGlob(pattern, ext(def, options)); } }, unescape: (s2, options = {}) => orig.unescape(s2, ext(def, options)), escape: (s2, options = {}) => orig.escape(s2, ext(def, options)), filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), defaults: (options) => orig.defaults(ext(def, options)), makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), sep: orig.sep, GLOBSTAR }); }; minimatch.defaults = defaults; var braceExpand = (pattern, options = {}) => { assertValidPattern(pattern); if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { return [pattern]; } return (0, import_brace_expansion.default)(pattern); }; minimatch.braceExpand = braceExpand; var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); minimatch.makeRe = makeRe; var match = (list, pattern, options = {}) => { const mm = new Minimatch(pattern, options); list = list.filter((f2) => mm.match(f2)); if (mm.options.nonull && !list.length) { list.push(pattern); } return list; }; minimatch.match = match; var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; var regExpEscape2 = (s2) => s2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); var Minimatch = class { constructor(pattern, options = {}) { __publicField(this, "options"); __publicField(this, "set"); __publicField(this, "pattern"); __publicField(this, "windowsPathsNoEscape"); __publicField(this, "nonegate"); __publicField(this, "negate"); __publicField(this, "comment"); __publicField(this, "empty"); __publicField(this, "preserveMultipleSlashes"); __publicField(this, "partial"); __publicField(this, "globSet"); __publicField(this, "globParts"); __publicField(this, "nocase"); __publicField(this, "isWindows"); __publicField(this, "platform"); __publicField(this, "windowsNoMagicRoot"); __publicField(this, "regexp"); assertValidPattern(pattern); options = options || {}; this.options = options; this.pattern = pattern; this.platform = options.platform || defaultPlatform; this.isWindows = this.platform === "win32"; this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; if (this.windowsPathsNoEscape) { this.pattern = this.pattern.replace(/\\/g, "/"); } this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; this.regexp = null; this.negate = false; this.nonegate = !!options.nonegate; this.comment = false; this.empty = false; this.partial = !!options.partial; this.nocase = !!this.options.nocase; this.windowsNoMagicRoot = options.windowsNoMagicRoot !== void 0 ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase); this.globSet = []; this.globParts = []; this.set = []; this.make(); } hasMagic() { if (this.options.magicalBraces && this.set.length > 1) { return true; } for (const pattern of this.set) { for (const part of pattern) { if (typeof part !== "string") return true; } } return false; } debug(..._2) { } make() { const pattern = this.pattern; const options = this.options; if (!options.nocomment && pattern.charAt(0) === "#") { this.comment = true; return; } if (!pattern) { this.empty = true; return; } this.parseNegate(); this.globSet = [...new Set(this.braceExpand())]; if (options.debug) { this.debug = (...args) => console.error(...args); } this.debug(this.pattern, this.globSet); const rawGlobParts = this.globSet.map((s2) => this.slashSplit(s2)); this.globParts = this.preprocess(rawGlobParts); this.debug(this.pattern, this.globParts); let set2 = this.globParts.map((s2, _2, __) => { if (this.isWindows && this.windowsNoMagicRoot) { const isUNC = s2[0] === "" && s2[1] === "" && (s2[2] === "?" || !globMagic.test(s2[2])) && !globMagic.test(s2[3]); const isDrive = /^[a-z]:/i.test(s2[0]); if (isUNC) { return [...s2.slice(0, 4), ...s2.slice(4).map((ss) => this.parse(ss))]; } else if (isDrive) { return [s2[0], ...s2.slice(1).map((ss) => this.parse(ss))]; } } return s2.map((ss) => this.parse(ss)); }); this.debug(this.pattern, set2); this.set = set2.filter((s2) => s2.indexOf(false) === -1); if (this.isWindows) { for (let i2 = 0; i2 < this.set.length; i2++) { const p2 = this.set[i2]; if (p2[0] === "" && p2[1] === "" && this.globParts[i2][2] === "?" && typeof p2[3] === "string" && /^[a-z]:$/i.test(p2[3])) { p2[2] = "?"; } } } this.debug(this.pattern, this.set); } // various transforms to equivalent pattern sets that are // faster to process in a filesystem walk. The goal is to // eliminate what we can, and push all ** patterns as far // to the right as possible, even if it increases the number // of patterns that we have to process. preprocess(globParts) { if (this.options.noglobstar) { for (let i2 = 0; i2 < globParts.length; i2++) { for (let j2 = 0; j2 < globParts[i2].length; j2++) { if (globParts[i2][j2] === "**") { globParts[i2][j2] = "*"; } } } } const { optimizationLevel = 1 } = this.options; if (optimizationLevel >= 2) { globParts = this.firstPhasePreProcess(globParts); globParts = this.secondPhasePreProcess(globParts); } else if (optimizationLevel >= 1) { globParts = this.levelOneOptimize(globParts); } else { globParts = this.adjascentGlobstarOptimize(globParts); } return globParts; } // just get rid of adjascent ** portions adjascentGlobstarOptimize(globParts) { return globParts.map((parts) => { let gs = -1; while (-1 !== (gs = parts.indexOf("**", gs + 1))) { let i2 = gs; while (parts[i2 + 1] === "**") { i2++; } if (i2 !== gs) { parts.splice(gs, i2 - gs); } } return parts; }); } // get rid of adjascent ** and resolve .. portions levelOneOptimize(globParts) { return globParts.map((parts) => { parts = parts.reduce((set2, part) => { const prev = set2[set2.length - 1]; if (part === "**" && prev === "**") { return set2; } if (part === "..") { if (prev && prev !== ".." && prev !== "." && prev !== "**") { set2.pop(); return set2; } } set2.push(part); return set2; }, []); return parts.length === 0 ? [""] : parts; }); } levelTwoFileOptimize(parts) { if (!Array.isArray(parts)) { parts = this.slashSplit(parts); } let didSomething = false; do { didSomething = false; if (!this.preserveMultipleSlashes) { for (let i2 = 1; i2 < parts.length - 1; i2++) { const p2 = parts[i2]; if (i2 === 1 && p2 === "" && parts[0] === "") continue; if (p2 === "." || p2 === "") { didSomething = true; parts.splice(i2, 1); i2--; } } if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) { didSomething = true; parts.pop(); } } let dd = 0; while (-1 !== (dd = parts.indexOf("..", dd + 1))) { const p2 = parts[dd - 1]; if (p2 && p2 !== "." && p2 !== ".." && p2 !== "**") { didSomething = true; parts.splice(dd - 1, 2); dd -= 2; } } } while (didSomething); return parts.length === 0 ? [""] : parts; } // First phase: single-pattern processing //
is 1 or more portions //is 1 or more portions // is any portion other than ., .., '', or ** //
is . or '' // // **/.. is *brutal* for filesystem walking performance, because // it effectively resets the recursive walk each time it occurs, // and ** cannot be reduced out by a .. pattern part like a regexp // or most strings (other than .., ., and '') can be. // // /**/..//
/
-> { /..//
/
, /**//
/
} // // -> /// //../
-> /// **/**/ -> **/ // // **/*/ -> */**/ <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(globParts) { let didSomething = false; do { didSomething = false; for (let parts of globParts) { let gs = -1; while (-1 !== (gs = parts.indexOf("**", gs + 1))) { let gss = gs; while (parts[gss + 1] === "**") { gss++; } if (gss > gs) { parts.splice(gs + 1, gss - gs); } let next = parts[gs + 1]; const p2 = parts[gs + 2]; const p22 = parts[gs + 3]; if (next !== "..") continue; if (!p2 || p2 === "." || p2 === ".." || !p22 || p22 === "." || p22 === "..") { continue; } didSomething = true; parts.splice(gs, 1); const other = parts.slice(0); other[gs] = "**"; globParts.push(other); gs--; } if (!this.preserveMultipleSlashes) { for (let i2 = 1; i2 < parts.length - 1; i2++) { const p2 = parts[i2]; if (i2 === 1 && p2 === "" && parts[0] === "") continue; if (p2 === "." || p2 === "") { didSomething = true; parts.splice(i2, 1); i2--; } } if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) { didSomething = true; parts.pop(); } } let dd = 0; while (-1 !== (dd = parts.indexOf("..", dd + 1))) { const p2 = parts[dd - 1]; if (p2 && p2 !== "." && p2 !== ".." && p2 !== "**") { didSomething = true; const needDot = dd === 1 && parts[dd + 1] === "**"; const splin = needDot ? ["."] : []; parts.splice(dd - 1, 2, ...splin); if (parts.length === 0) parts.push(""); dd -= 2; } } } } while (didSomething); return globParts; } // second phase: multi-pattern dedupes // { /*/, //
} -> /*/// { /, /} -> /// { /**/, /} -> /**/// // { /**/, /**//
} -> /**/// ^-- not valid because ** doens't follow symlinks secondPhasePreProcess(globParts) { for (let i2 = 0; i2 < globParts.length - 1; i2++) { for (let j2 = i2 + 1; j2 < globParts.length; j2++) { const matched = this.partsMatch(globParts[i2], globParts[j2], !this.preserveMultipleSlashes); if (matched) { globParts[i2] = []; globParts[j2] = matched; break; } } } return globParts.filter((gs) => gs.length); } partsMatch(a2, b2, emptyGSMatch = false) { let ai = 0; let bi = 0; let result = []; let which = ""; while (ai < a2.length && bi < b2.length) { if (a2[ai] === b2[bi]) { result.push(which === "b" ? b2[bi] : a2[ai]); ai++; bi++; } else if (emptyGSMatch && a2[ai] === "**" && b2[bi] === a2[ai + 1]) { result.push(a2[ai]); ai++; } else if (emptyGSMatch && b2[bi] === "**" && a2[ai] === b2[bi + 1]) { result.push(b2[bi]); bi++; } else if (a2[ai] === "*" && b2[bi] && (this.options.dot || !b2[bi].startsWith(".")) && b2[bi] !== "**") { if (which === "b") return false; which = "a"; result.push(a2[ai]); ai++; bi++; } else if (b2[bi] === "*" && a2[ai] && (this.options.dot || !a2[ai].startsWith(".")) && a2[ai] !== "**") { if (which === "a") return false; which = "b"; result.push(b2[bi]); ai++; bi++; } else { return false; } } return a2.length === b2.length && result; } parseNegate() { if (this.nonegate) return; const pattern = this.pattern; let negate = false; let negateOffset = 0; for (let i2 = 0; i2 < pattern.length && pattern.charAt(i2) === "!"; i2++) { negate = !negate; negateOffset++; } if (negateOffset) this.pattern = pattern.slice(negateOffset); this.negate = negate; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. matchOne(file, pattern, partial = false) { const options = this.options; if (this.isWindows) { const fileDrive = typeof file[0] === "string" && /^[a-z]:$/i.test(file[0]); const fileUNC = !fileDrive && file[0] === "" && file[1] === "" && file[2] === "?" && /^[a-z]:$/i.test(file[3]); const patternDrive = typeof pattern[0] === "string" && /^[a-z]:$/i.test(pattern[0]); const patternUNC = !patternDrive && pattern[0] === "" && pattern[1] === "" && pattern[2] === "?" && typeof pattern[3] === "string" && /^[a-z]:$/i.test(pattern[3]); const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0; const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0; if (typeof fdi === "number" && typeof pdi === "number") { const [fd, pd] = [file[fdi], pattern[pdi]]; if (fd.toLowerCase() === pd.toLowerCase()) { pattern[pdi] = fd; if (pdi > fdi) { pattern = pattern.slice(pdi); } else if (fdi > pdi) { file = file.slice(fdi); } } } } const { optimizationLevel = 1 } = this.options; if (optimizationLevel >= 2) { file = this.levelTwoFileOptimize(file); } this.debug("matchOne", this, { file, pattern }); this.debug("matchOne", file.length, pattern.length); for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { this.debug("matchOne loop"); var p2 = pattern[pi]; var f2 = file[fi]; this.debug(pattern, p2, f2); if (p2 === false) { return false; } if (p2 === GLOBSTAR) { this.debug("GLOBSTAR", [pattern, p2, f2]); var fr = fi; var pr = pi + 1; if (pr === pl) { this.debug("** at the end"); for (; fi < fl; fi++) { if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".") return false; } return true; } while (fr < fl) { var swallowee = file[fr]; this.debug("\nglobstar while", file, fr, pattern, pr, swallowee); if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { this.debug("globstar found match!", fr, fl, swallowee); return true; } else { if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") { this.debug("dot detected!", file, fr, pattern, pr); break; } this.debug("globstar swallow a segment, and continue"); fr++; } } if (partial) { this.debug("\n>>> no match, partial?", file, fr, pattern, pr); if (fr === fl) { return true; } } return false; } let hit; if (typeof p2 === "string") { hit = f2 === p2; this.debug("string match", p2, f2, hit); } else { hit = p2.test(f2); this.debug("pattern match", p2, f2, hit); } if (!hit) return false; } if (fi === fl && pi === pl) { return true; } else if (fi === fl) { return partial; } else if (pi === pl) { return fi === fl - 1 && file[fi] === ""; } else { throw new Error("wtf?"); } } braceExpand() { return braceExpand(this.pattern, this.options); } parse(pattern) { assertValidPattern(pattern); const options = this.options; if (pattern === "**") return GLOBSTAR; if (pattern === "") return ""; let m2; let fastTest = null; if (m2 = pattern.match(starRE)) { fastTest = options.dot ? starTestDot : starTest; } else if (m2 = pattern.match(starDotExtRE)) { fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m2[1]); } else if (m2 = pattern.match(qmarksRE)) { fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m2); } else if (m2 = pattern.match(starDotStarRE)) { fastTest = options.dot ? starDotStarTestDot : starDotStarTest; } else if (m2 = pattern.match(dotStarRE)) { fastTest = dotStarTest; } const re = AST.fromGlob(pattern, this.options).toMMPattern(); if (fastTest && typeof re === "object") { Reflect.defineProperty(re, "test", { value: fastTest }); } return re; } makeRe() { if (this.regexp || this.regexp === false) return this.regexp; const set2 = this.set; if (!set2.length) { this.regexp = false; return this.regexp; } const options = this.options; const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot; const flags = new Set(options.nocase ? ["i"] : []); let re = set2.map((pattern) => { const pp = pattern.map((p2) => { if (p2 instanceof RegExp) { for (const f2 of p2.flags.split("")) flags.add(f2); } return typeof p2 === "string" ? regExpEscape2(p2) : p2 === GLOBSTAR ? GLOBSTAR : p2._src; }); pp.forEach((p2, i2) => { const next = pp[i2 + 1]; const prev = pp[i2 - 1]; if (p2 !== GLOBSTAR || prev === GLOBSTAR) { return; } if (prev === void 0) { if (next !== void 0 && next !== GLOBSTAR) { pp[i2 + 1] = "(?:\\/|" + twoStar + "\\/)?" + next; } else { pp[i2] = twoStar; } } else if (next === void 0) { pp[i2 - 1] = prev + "(?:\\/|" + twoStar + ")?"; } else if (next !== GLOBSTAR) { pp[i2 - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next; pp[i2 + 1] = GLOBSTAR; } }); return pp.filter((p2) => p2 !== GLOBSTAR).join("/"); }).join("|"); const [open, close] = set2.length > 1 ? ["(?:", ")"] : ["", ""]; re = "^" + open + re + close + "$"; if (this.negate) re = "^(?!" + re + ").+$"; try { this.regexp = new RegExp(re, [...flags].join("")); } catch (ex) { this.regexp = false; } return this.regexp; } slashSplit(p2) { if (this.preserveMultipleSlashes) { return p2.split("/"); } else if (this.isWindows && /^\/\/[^\/]+/.test(p2)) { return ["", ...p2.split(/\/+/)]; } else { return p2.split(/\/+/); } } match(f2, partial = this.partial) { this.debug("match", f2, this.pattern); if (this.comment) { return false; } if (this.empty) { return f2 === ""; } if (f2 === "/" && partial) { return true; } const options = this.options; if (this.isWindows) { f2 = f2.split("\\").join("/"); } const ff = this.slashSplit(f2); this.debug(this.pattern, "split", ff); const set2 = this.set; this.debug(this.pattern, "set", set2); let filename = ff[ff.length - 1]; if (!filename) { for (let i2 = ff.length - 2; !filename && i2 >= 0; i2--) { filename = ff[i2]; } } for (let i2 = 0; i2 < set2.length; i2++) { const pattern = set2[i2]; let file = ff; if (options.matchBase && pattern.length === 1) { file = [filename]; } const hit = this.matchOne(file, pattern, partial); if (hit) { if (options.flipNegate) { return true; } return !this.negate; } } if (options.flipNegate) { return false; } return this.negate; } static defaults(def) { return minimatch.defaults(def).Minimatch; } }; minimatch.AST = AST; minimatch.Minimatch = Minimatch; minimatch.escape = escape; minimatch.unescape = unescape; // src/utils/fs.ts function isSupportedFileType(path3) { return path3.split(".").pop().toLowerCase() === "md"; } function pathMatchesPattern(path3, pattern) { return path3.startsWith(pattern) || minimatch(path3, pattern); } // src/algorithms/osr/osr-note-graph.ts var OsrNoteGraph = class { constructor(vaultNoteLinkInfoFinder) { // Key: targetFilename // Value: Map // This is the number of links from sourceFilename to targetFilename // For simplicity, we just store the filename without the directory or filename extension this.incomingLinks = {}; this.pageranks = {}; this.vaultNoteLinkInfoFinder = vaultNoteLinkInfoFinder; this.reset(); } reset() { this.incomingLinks = {}; this.pageranks = {}; graph.reset(); } processLinks(path3) { if (this.incomingLinks[path3] === void 0) { this.incomingLinks[path3] = []; } const targetLinks = this.vaultNoteLinkInfoFinder.getResolvedTargetLinksForNotePath(path3) || {}; for (const targetPath in targetLinks) { if (this.incomingLinks[targetPath] === void 0) this.incomingLinks[targetPath] = []; if (isSupportedFileType(targetPath)) { const linkCount = targetLinks[targetPath]; this.incomingLinks[targetPath].push({ sourcePath: path3, linkCount }); graph.link(path3, targetPath, linkCount); } } } calcNoteLinkStat(notePath, noteEaseList) { let linkTotal = 0, linkPGTotal = 0, totalLinkCount = 0; for (const statObj of this.incomingLinks[notePath] || []) { const ease = noteEaseList.getEaseByPath(statObj.sourcePath); if (ease) { linkTotal += statObj.linkCount * this.pageranks[statObj.sourcePath] * ease; linkPGTotal += this.pageranks[statObj.sourcePath] * statObj.linkCount; totalLinkCount += statObj.linkCount; } } const outgoingLinks = this.vaultNoteLinkInfoFinder.getResolvedTargetLinksForNotePath(notePath) || {}; for (const outgoingLink in outgoingLinks) { const ease = noteEaseList.getEaseByPath(outgoingLink); const linkCount = outgoingLinks[outgoingLink]; const pageRank = this.pageranks[outgoingLink]; if (ease) { linkTotal += linkCount * pageRank * ease; linkPGTotal += pageRank * linkCount; totalLinkCount += linkCount; } } return { linkTotal, linkPGTotal, totalLinkCount }; } generatePageRanks() { graph.rank(0.85, 1e-6, (node, rank2) => { this.pageranks[node] = rank2 * 1e4; }); } }; // src/data-store-algorithm/data-store-algorithm.ts var DataStoreAlgorithm = class _DataStoreAlgorithm { static getInstance() { if (!_DataStoreAlgorithm.instance) { throw new Error("there is no DataStoreAlgorithm instance."); } return _DataStoreAlgorithm.instance; } }; // src/data-stores/base/data-store.ts var DataStore = class _DataStore { static getInstance() { if (!_DataStore.instance) { throw new Error("there is no DataStore instance."); } return _DataStore.instance; } }; // src/topic-path.ts var TopicPath = class _TopicPath { constructor(path3) { if (path3 == null) throw "null path"; if (path3.some((str) => str.includes("/"))) throw "path entries must not contain '/'"; this.path = path3; } get hasPath() { return this.path.length > 0; } get isEmptyPath() { return !this.hasPath; } static get emptyPath() { return new _TopicPath([]); } shift() { if (this.isEmptyPath) throw "can't shift an empty path"; return this.path.shift(); } clone() { return new _TopicPath([...this.path]); } formatAsTag() { if (this.isEmptyPath) throw "Empty path"; const result = "#" + this.path.join("/"); return result; } static getTopicPathOfFile(noteFile, settings) { let deckPath = []; let result = _TopicPath.emptyPath; if (settings.convertFoldersToDecks) { deckPath = noteFile.path.split("/"); deckPath.pop(); if (deckPath.length != 0) { result = new _TopicPath(deckPath); } } else { const tagList = this.getTopicPathsFromTagList( noteFile.getAllTagsFromCache() ); outer: for (const tagToReview of this.getTopicPathsFromTagList( settings.flashcardTags )) { for (const tag of tagList) { if (tagToReview.isSameOrAncestorOf(tag)) { result = tag; break outer; } } } } return result; } isSameOrAncestorOf(topicPath) { if (this.isEmptyPath) return topicPath.isEmptyPath; if (this.path.length > topicPath.path.length) return false; for (let i2 = 0; i2 < this.path.length; i2++) { if (this.path[i2] != topicPath.path[i2]) return false; } return true; } static getTopicPathFromCardText(cardText) { var _a; const path3 = (_a = cardText.trimStart().match(OBSIDIAN_TAG_AT_STARTOFLINE_REGEX)) == null ? void 0 : _a.slice(-1)[0]; return (path3 == null ? void 0 : path3.length) > 0 ? _TopicPath.getTopicPathFromTag(path3) : null; } static getTopicPathsFromTagList(tagList) { const result = []; for (const tag of tagList) { if (this.isValidTag(tag)) result.push(_TopicPath.getTopicPathFromTag(tag)); } return result; } static isValidTag(tag) { if (tag == null || tag.length == 0) return false; if (tag[0] != "#") return false; if (tag.length == 1) return false; return true; } static getTopicPathFromTag(tag) { if (tag == null || tag.length == 0) throw "Null/empty tag"; if (tag[0] != "#") throw "Tag must start with #"; if (tag.length == 1) throw "Invalid tag"; const path3 = tag.replace("#", "").split("/").filter((str) => str); return new _TopicPath(path3); } static getFolderPathFromFilename(noteFile, settings) { let result = _TopicPath.emptyPath; if (settings.convertFoldersToDecks) { const deckPath = noteFile.path.split("/"); deckPath.pop(); if (deckPath.length != 0) { result = new _TopicPath(deckPath); } } return result; } }; var TopicPathList = class _TopicPathList { constructor(list, lineNum = null) { if (list == null) throw "TopicPathList null"; this.list = list; this.lineNum = lineNum; } get length() { return this.list.length; } isAnyElementSameOrAncestorOf(topicPath) { return this.list.some((item) => item.isSameOrAncestorOf(topicPath)); } formatPsv() { return this.format("|"); } format(sep2) { return this.list.map((topicPath) => topicPath.formatAsTag()).join(sep2); } static empty() { return new _TopicPathList([]); } static fromPsv(str, lineNum) { const result = _TopicPathList.convertTagListToTopicPathList(str.split("|")); result.lineNum = lineNum; return result; } // // tagList is a list of tags such as: // ["#flashcards/computing", "#boring-stuff", "#news-worthy"] // validTopicPathList is a list of valid tags, such as those from settings.flashcardTags,E.g. // ["#flashcards"] // // This returns a filtered version of tagList, containing only topic paths that are considered valid. // Validity is defined as "isAnyElementSameOrAncestorOf", and "#flashcards" is considered the ancestor of // "#flashcards/computing". // // Therefore this would return: // "#flashcards/computing" (but not "#boring-stuff" or "#news-worthy") // static filterValidTopicPathsFromTagList(list, validTopicPathList, lineNum = null) { const result = []; for (const tag of list.list) { if (validTopicPathList.isAnyElementSameOrAncestorOf(tag)) result.push(tag); } return new _TopicPathList(result, lineNum); } static convertTagListToTopicPathList(tagList) { const result = []; for (const tag of tagList) { if (TopicPath.isValidTag(tag)) result.push(TopicPath.getTopicPathFromTag(tag)); } return new _TopicPathList(result); } }; var TopicPathWithWs = class { constructor(topicPath, preWhitespace, postWhitespace) { if (!topicPath || topicPath.isEmptyPath) throw "topicPath null"; this.topicPath = topicPath; this.preWhitespace = preWhitespace; this.postWhitespace = postWhitespace; } formatWithWs() { return `${this.preWhitespace}${this.topicPath.formatAsTag()}${this.postWhitespace}`; } }; // src/flashcard-review-sequencer.ts var DeckStats = class { constructor(dueCount, newCount, totalCount) { this.dueCount = dueCount; this.newCount = newCount; this.totalCount = totalCount; } }; var FlashcardReviewSequencer = class { constructor(reviewMode, cardSequencer, settings, srsAlgorithm, questionPostponementList, dueDateFlashcardHistogram) { this.reviewMode = reviewMode; this.cardSequencer = cardSequencer; this.settings = settings; this.srsAlgorithm = srsAlgorithm; this.questionPostponementList = questionPostponementList; this.dueDateFlashcardHistogram = dueDateFlashcardHistogram; } get hasCurrentCard() { return this.cardSequencer.currentCard != null; } get currentCard() { return this.cardSequencer.currentCard; } get currentQuestion() { var _a; return (_a = this.currentCard) == null ? void 0 : _a.question; } get currentDeck() { return this.cardSequencer.currentDeck; } get currentNote() { return this.currentQuestion.note; } // originalDeckTree isn't modified by the review process // Only remainingDeckTree setDeckTree(originalDeckTree, remainingDeckTree) { this.cardSequencer.setBaseDeck(remainingDeckTree); this._originalDeckTree = originalDeckTree; this.remainingDeckTree = remainingDeckTree; this.setCurrentDeck(TopicPath.emptyPath); } setCurrentDeck(topicPath) { this.cardSequencer.setIteratorTopicPath(topicPath); this.cardSequencer.nextCard(); } get originalDeckTree() { return this._originalDeckTree; } getDeckStats(topicPath) { const totalCount = this._originalDeckTree.getDeck(topicPath).getDistinctCardCount(2 /* All */, true); const remainingDeck = this.remainingDeckTree.getDeck(topicPath); const newCount = remainingDeck.getDistinctCardCount(0 /* NewCard */, true); const dueCount = remainingDeck.getDistinctCardCount(1 /* DueCard */, true); return new DeckStats(dueCount, newCount, totalCount); } skipCurrentCard() { this.cardSequencer.deleteCurrentQuestionFromAllDecks(); } deleteCurrentCard() { this.cardSequencer.deleteCurrentCardFromAllDecks(); } async processReview(response) { switch (this.reviewMode) { case 1 /* Review */: await this.processReviewReviewMode(response); break; case 0 /* Cram */: await this.processReviewCramMode(response); break; } } async processReviewReviewMode(response) { if (response != 3 /* Reset */ || this.currentCard.hasSchedule) { const oldSchedule = this.currentCard.scheduleInfo; this.currentCard.scheduleInfo = this.determineCardSchedule(response, this.currentCard); await DataStore.getInstance().questionWriteSchedule(this.currentQuestion); if (oldSchedule) { const today = globalDateProvider.today.valueOf(); const nDays = Math.ceil( (oldSchedule.dueDateAsUnix - today) / TICKS_PER_DAY ); this.dueDateFlashcardHistogram.decrement(nDays); } this.dueDateFlashcardHistogram.increment(this.currentCard.scheduleInfo.interval); } if (response == 3 /* Reset */) { this.cardSequencer.moveCurrentCardToEndOfList(); this.cardSequencer.nextCard(); } else { if (this.settings.burySiblingCards) { await this.burySiblingCards(); this.cardSequencer.deleteCurrentQuestionFromAllDecks(); } else { this.deleteCurrentCard(); } } } async burySiblingCards() { const remaining = this.currentDeck.getQuestionCardCount(this.currentQuestion); if (remaining > 1) { this.questionPostponementList.add(this.currentQuestion); await this.questionPostponementList.write(); } } async processReviewCramMode(response) { if (response == 0 /* Easy */) this.deleteCurrentCard(); else { this.cardSequencer.moveCurrentCardToEndOfList(); this.cardSequencer.nextCard(); } } determineCardSchedule(response, card) { let result; if (response == 3 /* Reset */) { result = this.srsAlgorithm.cardGetResetSchedule(); } else { if (card.hasSchedule) { result = this.srsAlgorithm.cardCalcUpdatedSchedule( response, card.scheduleInfo, this.dueDateFlashcardHistogram ); } else { const currentNote = card.question.note; result = this.srsAlgorithm.cardGetNewSchedule( response, currentNote.filePath, this.dueDateFlashcardHistogram ); } } return result; } async updateCurrentQuestionText(text) { const q2 = this.currentQuestion.questionText; q2.actualQuestion = text; await DataStore.getInstance().questionWrite(this.currentQuestion); } }; // src/deck.ts var Deck2 = class _Deck { constructor(deckName, parent) { this.deckName = deckName; this.newFlashcards = []; this.dueFlashcards = []; this.subdecks = []; this.parent = parent; } getCardCount(cardListType, includeSubdeckCounts) { let result = 0; if (cardListType == 0 /* NewCard */ || cardListType == 2 /* All */) result += this.newFlashcards.length; if (cardListType == 1 /* DueCard */ || cardListType == 2 /* All */) result += this.dueFlashcards.length; if (includeSubdeckCounts) { for (const deck of this.subdecks) { result += deck.getCardCount(cardListType, includeSubdeckCounts); } } return result; } getDistinctCardCount(cardListType, includeSubdeckCounts) { const cardList = this.getFlattenedCardArray(cardListType, includeSubdeckCounts); const distinctCardSet = new Set(cardList); return distinctCardSet.size; } getFlattenedCardArray(cardListType, includeSubdeckCounts) { let result = []; switch (cardListType) { case 0 /* NewCard */: result = this.newFlashcards; break; case 1 /* DueCard */: result = this.dueFlashcards; break; case 2 /* All */: result = this.newFlashcards.concat(this.dueFlashcards); } if (includeSubdeckCounts) { for (const subdeck of this.subdecks) { result = result.concat( subdeck.getFlattenedCardArray(cardListType, includeSubdeckCounts) ); } } return result; } // Returns a count of the number of this question's cards are present in this deck. // (The returned value would be <= question.cards.length) getQuestionCardCount(question) { let result = 0; result += this.getQuestionCardCountForCardListType(question, this.newFlashcards); result += this.getQuestionCardCountForCardListType(question, this.dueFlashcards); return result; } getQuestionCardCountForCardListType(question, cards) { let result = 0; for (let i2 = 0; i2 < cards.length; i2++) { if (Object.is(question, cards[i2].question)) result++; } return result; } static get emptyDeck() { return new _Deck("Root", null); } get isRootDeck() { return this.parent == null; } getDeckByTopicTag(tag) { return this.getDeck(TopicPath.getTopicPathFromTag(tag)); } getDeck(topicPath) { return this._getOrCreateDeck(topicPath, false); } getOrCreateDeck(topicPath) { return this._getOrCreateDeck(topicPath, true); } _getOrCreateDeck(topicPath, createAllowed) { if (!topicPath.hasPath) { return this; } const t3 = topicPath.clone(); const deckName = t3.shift(); for (const subdeck of this.subdecks) { if (deckName === subdeck.deckName) { return subdeck._getOrCreateDeck(t3, createAllowed); } } let result = null; if (createAllowed) { const subdeck = new _Deck( deckName, this /* parent */ ); this.subdecks.push(subdeck); result = subdeck._getOrCreateDeck(t3, createAllowed); } return result; } getTopicPath() { const list = []; let deck = this; while (!deck.isRootDeck) { list.push(deck.deckName); deck = deck.parent; } return new TopicPath(list.reverse()); } getRootDeck() { let deck = this; while (!deck.isRootDeck) { deck = deck.parent; } return deck; } getCard(index, cardListType) { const cardList = this.getCardListForCardType(cardListType); return cardList[index]; } getCardListForCardType(cardListType) { return cardListType == 1 /* DueCard */ ? this.dueFlashcards : this.newFlashcards; } appendCard(topicPathList, cardObj) { if (topicPathList.list.length == 0) { this.appendCardToRootDeck(cardObj); } else { for (const topicPath of topicPathList.list) { this.appendCardSingleTopic(topicPath, cardObj); } } } appendCardToRootDeck(cardObj) { this.appendCardSingleTopic(TopicPath.emptyPath, cardObj); } appendCardSingleTopic(topicPath, cardObj) { const deck = this.getOrCreateDeck(topicPath); const cardList = deck.getCardListForCardType(cardObj.cardListType); cardList.push(cardObj); } // The question lists all the topics in which this card is included. // The topics are relative to the base deck, and this method must be called on that deck deleteQuestionFromAllDecks(question, exceptionIfMissing) { for (const card of question.cards) { this.deleteCardFromAllDecks(card, exceptionIfMissing); } } deleteQuestion(question, exceptionIfMissing) { for (const card of question.cards) { this.deleteCardFromThisDeck(card, exceptionIfMissing); } } // The card's question lists all the topics in which this card is included. // The topics are relative to the base deck, and this method must be called on that deck deleteCardFromAllDecks(card, exceptionIfMissing) { for (const topicPath of card.question.topicPathList.list) { const deck = this.getDeck(topicPath); deck.deleteCardFromThisDeck(card, exceptionIfMissing); } } deleteCardFromThisDeck(card, exceptionIfMissing) { const newIdx = this.newFlashcards.indexOf(card); if (newIdx != -1) this.newFlashcards.splice(newIdx, 1); const dueIdx = this.dueFlashcards.indexOf(card); if (dueIdx != -1) this.dueFlashcards.splice(dueIdx, 1); if (newIdx == -1 && dueIdx == -1 && exceptionIfMissing) { throw `deleteCardFromThisDeck: Card: ${card.front} not found in deck: ${this.deckName}`; } } deleteCardAtIndex(index, cardListType) { const cardList = this.getCardListForCardType(cardListType); cardList.splice(index, 1); } toDeckArray() { const result = []; result.push(this); for (const subdeck of this.subdecks) { result.push(...subdeck.toDeckArray()); } return result; } sortSubdecksList() { this.subdecks.sort((a2, b2) => { if (a2.deckName < b2.deckName) { return -1; } else if (a2.deckName > b2.deckName) { return 1; } return 0; }); for (const deck of this.subdecks) { deck.sortSubdecksList(); } } debugLogToConsole(desc = null, indent = 0) { let str = desc != null ? `${desc}: ` : ""; console.log(str += this.toString(indent)); } toString(indent = 0) { let result = ""; let indentStr = " ".repeat(indent * 4); result += `${indentStr}${this.deckName}\r `; indentStr += " "; for (let i2 = 0; i2 < this.newFlashcards.length; i2++) { const card = this.newFlashcards[i2]; result += `${indentStr}New: ${i2}: ${card.front}::${card.back}\r `; } for (let i2 = 0; i2 < this.dueFlashcards.length; i2++) { const card = this.dueFlashcards[i2]; const s2 = card.isDue ? "Due" : "Not due"; result += `${indentStr}${s2}: ${i2}: ${card.front}::${card.back}\r `; } for (const subdeck of this.subdecks) { result += subdeck.toString(indent + 1); } return result; } clone() { return this.copyWithCardFilter(() => true); } copyWithCardFilter(predicate, parent = null) { const result = new _Deck(this.deckName, parent); result.newFlashcards = [...this.newFlashcards.filter((card) => predicate(card))]; result.dueFlashcards = [...this.dueFlashcards.filter((card) => predicate(card))]; for (const s2 of this.subdecks) { const newParent = result; const newDeck = s2.copyWithCardFilter(predicate, newParent); result.subdecks.push(newDeck); } return result; } static otherListType(cardListType) { let result; if (cardListType == 0 /* NewCard */) result = 1 /* DueCard */; else if (cardListType == 1 /* DueCard */) result = 0 /* NewCard */; else throw "Invalid cardListType"; return result; } }; var DeckTreeFilter = class { static filterForReviewableCards(reviewableDeckTree) { return reviewableDeckTree.copyWithCardFilter((card) => !card.question.hasEditLaterTag); } static filterForRemainingCards(questionPostponementList, deckTree, reviewMode) { return deckTree.copyWithCardFilter( (card) => (reviewMode == 0 /* Cram */ || card.isNew || card.isDue) && !questionPostponementList.includes(card.question) ); } }; // src/utils/types.ts function getTypedObjectEntries(obj) { return Object.entries(obj); } var getKeysPreserveType = Object.keys; function mapRecord(record, transform) { return Object.fromEntries( Object.entries(record).map(([key, value]) => transform(key, value)) ); } // src/utils/numbers.ts var ValueCountDict = class { constructor() { this.dict = {}; } // Record clearCountIfMissing(value) { if (!this.hasValue(value)) this.dict[value] = 0; } hasValue(value) { return Object.prototype.hasOwnProperty.call(this.dict, value); } incrementCount(value) { this.clearCountIfMissing(value); this.dict[value]++; } getMaxValue() { return Math.max(...getKeysPreserveType(this.dict)) || 0; } getTotalOfValueMultiplyCount() { const v2 = getTypedObjectEntries(this.dict).map(([value, count]) => value * count).reduce((a2, b2) => a2 + b2, 0) || 0; return v2; } }; var RandomNumberProvider = class { getInteger(lowerBound, upperBound) { const range = upperBound - lowerBound + 1; return Math.floor(Math.random() * range) + lowerBound; } }; var StaticRandomNumberProvider = class { getInteger(lowerBound, upperBound) { if (lowerBound != this.expectedLowerBound || upperBound != this.expectedUpperBound) throw `lowerBound: A${lowerBound}/E${this.expectedLowerBound}, upperBound: A${upperBound}/E${this.expectedUpperBound}`; return this.next; } }; var WeightedRandomNumber = class _WeightedRandomNumber { constructor(provider) { this.provider = provider; } static create() { return new _WeightedRandomNumber(globalRandomNumberProvider); } // weights is a dictionary: // first number - a key that can be returned // second number - the "bucket size" - this is a weight that influences the probability of the // first number being returned // // returns: // first number - one of the keys from the weights parameter // second number - an "index" value; 0 <= index < bucketSize getRandomValues(weights) { const total = _WeightedRandomNumber.calcTotalOfCount(weights); if (Object.values(weights).some((i2) => !Number.isInteger(i2) || i2 < 0)) throw "All weights must be positive integers"; const v2 = this.provider.getInteger(0, total - 1); let x2 = 0; for (const kvp in weights) { const [value, count] = [Number(kvp), weights[kvp]]; if (v2 < x2 + count) { const index = v2 - x2; return [value, index]; } x2 += count; } throw ""; } static calcTotalOfCount(weights) { const total = getTypedObjectEntries(weights).map(([_2, count]) => count).reduce((a2, b2) => a2 + b2, 0) || 0; return total; } }; var globalRandomNumberProvider = new RandomNumberProvider(); var staticRandomNumberProvider = new StaticRandomNumberProvider(); // src/deck-tree-iterator.ts var CardOrder = /* @__PURE__ */ ((CardOrder2) => { CardOrder2[CardOrder2["NewFirstSequential"] = 0] = "NewFirstSequential"; CardOrder2[CardOrder2["NewFirstRandom"] = 1] = "NewFirstRandom"; CardOrder2[CardOrder2["DueFirstSequential"] = 2] = "DueFirstSequential"; CardOrder2[CardOrder2["DueFirstRandom"] = 3] = "DueFirstRandom"; CardOrder2[CardOrder2["EveryCardRandomDeckAndCard"] = 4] = "EveryCardRandomDeckAndCard"; return CardOrder2; })(CardOrder || {}); var DeckOrder = /* @__PURE__ */ ((DeckOrder2) => { DeckOrder2[DeckOrder2["PrevDeckComplete_Sequential"] = 0] = "PrevDeckComplete_Sequential"; DeckOrder2[DeckOrder2["PrevDeckComplete_Random"] = 1] = "PrevDeckComplete_Random"; return DeckOrder2; })(DeckOrder || {}); var SingleDeckIterator = class _SingleDeckIterator { get hasCurrentCard() { return this.cardIdx != null; } get currentCard() { let result = null; if (this.cardIdx != null) result = this.deck.getCard(this.cardIdx, this.cardListType); return result; } constructor(iteratorOrder) { this.iteratorOrder = iteratorOrder; this.preferredCardListType = _SingleDeckIterator.getCardListTypeForIterator( this.iteratorOrder ); this.weightedRandomNumber = WeightedRandomNumber.create(); } setDeck(deck) { this.deck = deck; this.setCardListType(null); } // // 0 <= cardIndex < newFlashcards.length + dueFlashcards.length // setNewOrDueCardIdx(cardIndex) { let cardListType = 0 /* NewCard */; let index = cardIndex; if (cardIndex >= this.deck.newFlashcards.length) { cardListType = 1 /* DueCard */; index = cardIndex - this.deck.newFlashcards.length; } this.setCardListType(cardListType, index); } setCardListType(cardListType, cardIdx = null) { this.cardListType = cardListType; this.cardIdx = cardIdx; } nextCard() { if (this.iteratorOrder.cardOrder == 4 /* EveryCardRandomDeckAndCard */) { this.nextRandomCard(); } else { if (this.cardListType == null) { this.setCardListType(this.preferredCardListType); } if (!this.nextCardWithinCurrentList()) { if (this.cardListType == this.preferredCardListType) { this.setCardListType(Deck2.otherListType(this.cardListType)); if (!this.nextCardWithinCurrentList()) { this.setCardListType(null); } } else { this.cardIdx = null; } } } return this.cardIdx != null; } nextRandomCard() { const newCount = this.deck.newFlashcards.length; const dueCount = this.deck.dueFlashcards.length; if (newCount + dueCount > 0) { const weights = {}; if (newCount > 0) weights[0 /* NewCard */] = newCount; if (dueCount > 0) weights[1 /* DueCard */] = dueCount; const [cardListType, index] = this.weightedRandomNumber.getRandomValues(weights); this.setCardListType(cardListType, index); } else { this.setCardListType(null); } } nextCardWithinCurrentList() { const cardList = this.deck.getCardListForCardType(this.cardListType); const result = cardList.length > 0; if (result) { switch (this.iteratorOrder.cardOrder) { case 2 /* DueFirstSequential */: case 0 /* NewFirstSequential */: this.cardIdx = 0; break; case 3 /* DueFirstRandom */: case 1 /* NewFirstRandom */: this.cardIdx = globalRandomNumberProvider.getInteger(0, cardList.length - 1); break; } } return result; } moveCurrentCardToEndOfList() { this.ensureCurrentCard(); const cardList = this.deck.getCardListForCardType(this.cardListType); if (cardList.length <= 1) return; const card = this.currentCard; this.deck.deleteCardAtIndex(this.cardIdx, this.cardListType); this.deck.appendCardToRootDeck(card); this.setNoCurrentCard(); } setNoCurrentCard() { this.cardIdx = null; } ensureCurrentCard() { if (this.cardIdx == null || this.cardListType == null) throw "no current card"; } static getCardListTypeForIterator(iteratorOrder) { let result = null; switch (iteratorOrder.cardOrder) { case 3 /* DueFirstRandom */: case 2 /* DueFirstSequential */: result = 1 /* DueCard */; break; case 1 /* NewFirstRandom */: case 0 /* NewFirstSequential */: result = 0 /* NewCard */; break; } return result; } }; var DeckTreeIterator = class _DeckTreeIterator { get hasCurrentCard() { return this.deckIdx != null && this.singleDeckIterator.hasCurrentCard; } get currentTopicPath() { var _a; return (_a = this.currentDeck) == null ? void 0 : _a.getTopicPath(); } get currentDeck() { if (this.deckIdx == null) return null; return this.deckArray[this.deckIdx]; } get currentCard() { let result = null; if (this.deckIdx != null && this.singleDeckIterator.hasCurrentCard) result = this.singleDeckIterator.currentCard; return result; } get currentQuestion() { var _a; return (_a = this.currentCard) == null ? void 0 : _a.question; } constructor(iteratorOrder, baseDeckTree) { this.singleDeckIterator = new SingleDeckIterator(iteratorOrder); this.iteratorOrder = iteratorOrder; this.weightedRandomNumber = WeightedRandomNumber.create(); this.setBaseDeck(baseDeckTree); } setBaseDeck(baseDeck) { this.baseDeckTree = baseDeck; this.singleDeckIterator.setNoCurrentCard(); } setIteratorTopicPath(topicPath) { const iteratorDeck = this.baseDeckTree.getDeck(topicPath); this.deckArray = _DeckTreeIterator.filterForDecksWithCards(iteratorDeck.toDeckArray()); this.setDeckIdx(null); } static filterForDecksWithCards(sourceArray) { const result = []; for (let idx = 0; idx < sourceArray.length; idx++) { const deck = sourceArray[idx]; const hasAnyCards = deck.getCardCount(2 /* All */, false) > 0; if (hasAnyCards) { result.push(deck); } } return result; } setDeckIdx(deckIdx) { this.deckIdx = deckIdx; if (deckIdx != null) this.singleDeckIterator.setDeck(this.deckArray[deckIdx]); } nextCard() { let result = false; if (this.hasCurrentCard) { this.baseDeckTree.deleteCardFromAllDecks(this.currentCard, true); } if (this.iteratorOrder.cardOrder == 4 /* EveryCardRandomDeckAndCard */) { result = this.nextCardEveryCardRandomDeck(); } else { if (this.deckIdx == null) { this.chooseNextDeck(true); } while (this.deckIdx < this.deckArray.length) { if (this.singleDeckIterator.nextCard()) { result = true; break; } this.chooseNextDeck(false); } } if (!result) this.deckIdx = null; return result; } chooseNextDeck(firstTime) { switch (this.iteratorOrder.deckOrder) { case 0 /* PrevDeckComplete_Sequential */: this.deckIdx = firstTime ? 0 : this.deckIdx + 1; break; case 1 /* PrevDeckComplete_Random */: { const weights = {}; let hasDeck = false; for (let i2 = 0; i2 < this.deckArray.length; i2++) { if (this.deckArray[i2].getCardCount(2 /* All */, false)) { weights[i2] = 1; hasDeck = true; } } if (hasDeck) { const [deckIdx, _2] = this.weightedRandomNumber.getRandomValues(weights); this.deckIdx = deckIdx; } else { this.deckIdx = this.deckArray.length; } break; } } if (this.deckIdx < this.deckArray.length) { this.singleDeckIterator.setDeck(this.deckArray[this.deckIdx]); } } nextCardEveryCardRandomDeck() { const weights = {}; for (let i2 = 0; i2 < this.deckArray.length; i2++) { const cardCount = this.deckArray[i2].getCardCount(2 /* All */, false); if (cardCount) { weights[i2] = cardCount; } } if (Object.keys(weights).length == 0) return false; const [deckIdx, cardIdx] = this.weightedRandomNumber.getRandomValues(weights); this.setDeckIdx(deckIdx); this.singleDeckIterator.setNewOrDueCardIdx(cardIdx); return true; } deleteCurrentQuestionFromAllDecks() { this.singleDeckIterator.ensureCurrentCard(); this.baseDeckTree.deleteQuestionFromAllDecks(this.currentQuestion, false); this.singleDeckIterator.setNoCurrentCard(); return this.nextCard(); } deleteCurrentCardFromAllDecks() { this.singleDeckIterator.ensureCurrentCard(); this.baseDeckTree.deleteCardFromAllDecks(this.currentCard, true); this.singleDeckIterator.setNoCurrentCard(); return this.nextCard(); } moveCurrentCardToEndOfList() { this.singleDeckIterator.moveCurrentCardToEndOfList(); } removeCurrentDeckIfEmpty() { if (this.currentDeck.getCardCount(2 /* All */, false) == 0) { this.deckArray.splice(this.deckIdx, 1); if (this.deckIdx < this.deckArray.length) this.setDeckIdx(this.deckIdx); } } }; // src/stats.ts var Stats = class { constructor() { this.eases = new ValueCountDict(); this.intervals = new ValueCountDict(); this.delayedDays = new ValueCountDict(); this.newCount = 0; this.youngCount = 0; this.matureCount = 0; } get totalCount() { return this.youngCount + this.matureCount; } incrementNew() { this.newCount++; } update(delayedDays, interval, ease) { this.intervals.incrementCount(interval); this.eases.incrementCount(ease); this.delayedDays.incrementCount(delayedDays); if (interval >= 32) { this.matureCount++; } else { this.youngCount++; } } getMaxInterval() { return this.intervals.getMaxValue(); } getAverageInterval() { return this.intervals.getTotalOfValueMultiplyCount() / this.totalCount; } getAverageEases() { return this.eases.getTotalOfValueMultiplyCount() / this.totalCount; } }; // src/deck-tree-stats-calculator.ts var DeckTreeStatsCalculator = class { calculate(deckTree) { const iteratorOrder = { deckOrder: 0 /* PrevDeckComplete_Sequential */, cardOrder: 2 /* DueFirstSequential */ }; const iterator = new DeckTreeIterator(iteratorOrder, deckTree.clone()); const result = new Stats(); iterator.setIteratorTopicPath(TopicPath.emptyPath); while (iterator.nextCard()) { const card = iterator.currentCard; if (card.hasSchedule) { const schedule = card.scheduleInfo; result.update( schedule.delayedBeforeReviewDaysInt(), schedule.interval, schedule.latestEase ); } else { result.incrementNew(); } } return result; } }; // src/due-date-histogram.ts var _DueDateHistogram = class _DueDateHistogram { constructor(rec = null) { // Key - # of days in future // Value - Count of notes due this.dueDatesMap = /* @__PURE__ */ new Map(); this.dueDatesMap = /* @__PURE__ */ new Map(); if (rec != null) { Object.entries(rec).forEach(([key, value]) => { this.dueDatesMap.set(Number(key), value); }); } } get dueNotesCount() { let result = 0; if (this.dueDatesMap.has(_DueDateHistogram.dueNowNDays)) result = this.dueDatesMap.get(_DueDateHistogram.dueNowNDays); return result; } hasEntryForDays(days) { return this.dueDatesMap.has(days); } set(days, value) { this.dueDatesMap.set(days, value); } get(days) { return this.dueDatesMap.get(days); } increment(days) { let value = 0; if (this.dueDatesMap.has(days)) { value = this.dueDatesMap.get(days); } this.dueDatesMap.set(days, value + 1); } decrement(days) { let value = 0; if (this.dueDatesMap.has(days)) value = this.dueDatesMap.get(days); if (value > 0) { this.dueDatesMap.set(days, value - 1); } } findLeastUsedIntervalOverRange(originalInterval, fuzz) { if (!this.hasEntryForDays(originalInterval)) { return originalInterval; } let interval = originalInterval; outer: for (let i2 = 1; i2 <= fuzz; i2++) { for (const ivl of [originalInterval - i2, originalInterval + i2]) { if (!this.hasEntryForDays(ivl)) { interval = ivl; break outer; } if (this.dueDatesMap.get(ivl) < this.dueDatesMap.get(interval)) interval = ivl; } } return interval; } }; // The key for dueDatesNotes is the number of days after today // therefore the key to lookup how many cards are due today is 0 _DueDateHistogram.dueNowNDays = 0; var DueDateHistogram = _DueDateHistogram; var NoteDueDateHistogram = class extends DueDateHistogram { calculateFromReviewDecksAndSort(reviewDecks, osrNoteGraph) { this.dueDatesMap = /* @__PURE__ */ new Map(); const today = globalDateProvider.today.valueOf(); reviewDecks.forEach((reviewDeck) => { reviewDeck.scheduledNotes.forEach((scheduledNote) => { const nDays = Math.ceil((scheduledNote.dueUnix - today) / TICKS_PER_DAY); this.increment(nDays); }); reviewDeck.sortNotesByDateAndImportance(osrNoteGraph.pageranks); }); } }; var CardDueDateHistogram = class extends DueDateHistogram { calculateFromDeckTree(deckTree) { this.dueDatesMap = /* @__PURE__ */ new Map(); const iteratorOrder = { deckOrder: 0 /* PrevDeckComplete_Sequential */, cardOrder: 2 /* DueFirstSequential */ }; const today = globalDateProvider.today.valueOf(); const iterator = new DeckTreeIterator(iteratorOrder, deckTree.clone()); iterator.setIteratorTopicPath(TopicPath.emptyPath); while (iterator.nextCard()) { const card = iterator.currentCard; if (card.hasSchedule) { const scheduledCard = card.scheduleInfo; const nDays = Math.ceil( (scheduledCard.dueDateAsUnix - today) / TICKS_PER_DAY ); this.increment(nDays); } } } }; // src/file.ts var import_obsidian2 = require("obsidian"); // src/utils/strings.ts function literalStringReplace(text, searchStr, replacementStr) { let result = text; const startIdx = text.indexOf(searchStr); if (startIdx >= 0) { const startStr = text.substring(0, startIdx); const endIdx = startIdx + searchStr.length; const endStr = text.substring(endIdx); result = startStr + replacementStr + endStr; } return result; } function cyrb53(str, seed = 0) { let h12 = 3735928559 ^ seed, h22 = 1103547991 ^ seed; for (let i2 = 0, ch; i2 < str.length; i2++) { ch = str.charCodeAt(i2); h12 = Math.imul(h12 ^ ch, 2654435761); h22 = Math.imul(h22 ^ ch, 1597334677); } h12 = Math.imul(h12 ^ h12 >>> 16, 2246822507) ^ Math.imul(h22 ^ h22 >>> 13, 3266489909); h22 = Math.imul(h22 ^ h22 >>> 16, 2246822507) ^ Math.imul(h12 ^ h12 >>> 13, 3266489909); return (4294967296 * (2097151 & h22) + (h12 >>> 0)).toString(16); } function convertToStringOrEmpty(v2) { let result = ""; if (v2 != null && v2 != void 0) { result = v2 + ""; } return result; } function splitTextIntoLineArray(text) { return text.replaceAll(/\r\n|\r/g, "\n").split("\n"); } function stringTrimStart(str) { if (!str) { return ["", ""]; } const trimmed = str.trimStart(); const wsCount = str.length - trimmed.length; const ws = str.substring(0, wsCount); return [ws, trimmed]; } function splitNoteIntoFrontmatterAndContent(str) { const lines = splitTextIntoLineArray(str); let lineIndex = 0; let hasFrontmatter = false; do { if (lineIndex === 0 && lines[lineIndex] === "---") { hasFrontmatter = true; } else if (hasFrontmatter && lines[lineIndex] === "---") { hasFrontmatter = false; lineIndex++; } if (hasFrontmatter) { lineIndex++; } } while (hasFrontmatter && lineIndex < lines.length); if (hasFrontmatter) { lineIndex = 0; } const frontmatter = lines.slice(0, lineIndex).join("\n"); const emptyLines = lineIndex > 0 ? Array(lineIndex).join(".").split(".") : []; const content = emptyLines.concat(lines.slice(lineIndex)).join("\n"); return [frontmatter, content]; } function findLineIndexOfSearchStringIgnoringWs(lines, searchString) { let result = -1; for (let i2 = 0; i2 < lines.length; i2++) { if (lines[i2].trim() == searchString) { result = i2; break; } } return result; } function parseObsidianFrontmatterTag(tagStr) { const result = []; if (tagStr) { const tagStrList = tagStr.split(","); for (const tag of tagStrList) { if (tag !== "") { result.push(tag.startsWith("#") ? tag : "#" + tag); } } } return result; } var MultiLineTextFinder = class _MultiLineTextFinder { static findAndReplace(sourceText, searchText, replacementText) { let result = null; if (sourceText.includes(searchText)) { result = literalStringReplace(sourceText, searchText, replacementText); } else { const sourceTextArray = splitTextIntoLineArray(sourceText); const searchTextArray = splitTextIntoLineArray(searchText); const lineNo = _MultiLineTextFinder.find( sourceTextArray, searchTextArray ); if (lineNo !== null) { const replacementTextArray = splitTextIntoLineArray(replacementText); const linesToRemove = searchTextArray.length; sourceTextArray.splice(lineNo, linesToRemove, ...replacementTextArray); result = sourceTextArray.join("\n"); } } return result; } static find(sourceText, searchText) { let result = null; let searchIdx = 0; const maxSearchIdx = searchText.length - 1; for (let sourceIdx = 0; sourceIdx < sourceText.length; sourceIdx++) { const sourceLine = sourceText[sourceIdx].trim(); const searchLine = searchText[searchIdx].trim(); if (searchLine == sourceLine) { if (searchIdx == maxSearchIdx) { result = sourceIdx - searchIdx; break; } searchIdx++; } else { searchIdx = 0; } } return result; } }; // src/file.ts var frontmatterTagPseudoLineNum = -1; var SrTFile = class { constructor(vault, metadataCache, file) { this.vault = vault; this.metadataCache = metadataCache; this.file = file; } get path() { return this.file.path; } get basename() { return this.file.basename; } get tfile() { return this.file; } async getFrontmatter() { const fileCachedData = this.metadataCache.getFileCache(this.file) || {}; const frontmatter = fileCachedData.frontmatter || {}; const result = /* @__PURE__ */ new Map(); for (const [key, value] of Object.entries(frontmatter)) { const v2 = Array.isArray(value) && value.length > 0 ? value[0] : value; const vStr = v2 + ""; result.set(key, vStr); } return result; } getAllTagsFromCache() { const fileCachedData = this.metadataCache.getFileCache(this.file) || {}; const result = (0, import_obsidian2.getAllTags)(fileCachedData) || []; return result; } getAllTagsFromText() { var _a; const result = []; const fileCachedData = this.metadataCache.getFileCache(this.file) || {}; if (((_a = fileCachedData.tags) == null ? void 0 : _a.length) > 0) { result.push(...fileCachedData.tags); } result.push(...this.getFrontmatterTags(fileCachedData.frontmatter)); return result; } getFrontmatterTags(frontmatter) { const result = []; const frontmatterTags = frontmatter != null ? frontmatter["tags"] + "" : null; if (frontmatterTags) { const tagStrList = parseObsidianFrontmatterTag(frontmatterTags); for (const str of tagStrList) { const tag = { tag: str, position: { start: { line: frontmatterTagPseudoLineNum, col: null, offset: null }, end: { line: frontmatterTagPseudoLineNum, col: null, offset: null } } }; result.push(tag); } } return result; } getQuestionContext(cardLine) { const fileCachedData = this.metadataCache.getFileCache(this.file) || {}; const headings = fileCachedData.headings || []; const stack = []; for (const heading of headings) { if (heading.position.start.line > cardLine) { break; } while (stack.length > 0 && stack[stack.length - 1].level >= heading.level) { stack.pop(); } stack.push(heading); } const result = []; for (const headingObj of stack) { headingObj.heading = headingObj.heading.replace(/\[\^\d+\]/gm, "").trim(); result.push(headingObj.heading); } return result; } getTextDirection() { let result = 0 /* Unspecified */; const fileCache = this.metadataCache.getFileCache(this.file); const frontMatter = fileCache == null ? void 0 : fileCache.frontmatter; if (frontMatter && (frontMatter == null ? void 0 : frontMatter.direction)) { const str = (frontMatter.direction + "").toLowerCase(); result = str == "rtl" ? 2 /* Rtl */ : 1 /* Ltr */; } return result; } async read() { return await this.vault.read(this.file); } async write(content) { await this.vault.modify(this.file, content); } }; // src/note.ts var Note = class { get hasChanged() { return this.questionList.some((question) => question.hasChanged); } get filePath() { return this.file.path; } constructor(file, questionList) { this.file = file; this.questionList = questionList; questionList.forEach((question) => question.note = this); } appendCardsToDeck(deck) { for (const question of this.questionList) { for (const card of question.cards) { deck.appendCard(question.topicPathList, card); } } } debugLogToConsole(desc = "") { var _a; let str = `Note: ${desc}: ${this.questionList.length} questions\r `; for (let i2 = 0; i2 < this.questionList.length; i2++) { const q2 = this.questionList[i2]; str += `[${i2}]: ${q2.questionType}: ${q2.lineNo}: ${(_a = q2.topicPathList) == null ? void 0 : _a.format("|")}: ${q2.questionText.original}\r `; } console.debug(str); } async writeNoteFile(settings) { let fileText = await this.file.read(); for (const question of this.questionList) { if (question.hasChanged) { fileText = question.updateQuestionWithinNoteText(fileText, settings); } } await this.file.write(fileText); this.questionList.forEach((question) => question.hasChanged = false); } }; // src/card.ts var Card = class extends RepetitionItem { constructor(init) { super(); Object.assign(this, init); } get cardListType() { return this.isNew ? 0 /* NewCard */ : 1 /* DueCard */; } formatSchedule() { let result = ""; if (this.hasSchedule) result = this.scheduleInfo.formatCardScheduleForHtmlComment(); else result = "New"; return result; } }; // src/parser.ts var import_clozecraft = __toESM(require_dist()); // src/question.ts var QuestionText = class _QuestionText { constructor(original, topicPathWithWs, actualQuestion, textDirection, blockId) { this.original = original; this.topicPathWithWs = topicPathWithWs; this.actualQuestion = actualQuestion; this.textDirection = textDirection; this.obsidianBlockId = blockId; this.textHash = cyrb53(this.formatTopicAndQuestion()); } endsWithCodeBlock() { return this.actualQuestion.endsWith("```"); } static create(original, textDirection, settings) { const [topicPathWithWs, actualQuestion, blockId] = this.splitText(original, settings); return new _QuestionText(original, topicPathWithWs, actualQuestion, textDirection, blockId); } static splitText(original, settings) { const originalWithoutSR = DataStore.getInstance().questionRemoveScheduleInfo(original); let actualQuestion = originalWithoutSR.trimEnd(); let topicPathWithWs = null; let blockId = null; const topicPath = TopicPath.getTopicPathFromCardText(originalWithoutSR); if (topicPath == null ? void 0 : topicPath.hasPath) { const [preTopicPathWs, cardText2] = stringTrimStart(originalWithoutSR); const cardText3 = cardText2.replaceAll(OBSIDIAN_TAG_AT_STARTOFLINE_REGEX, ""); let postTopicPathWs = null; [postTopicPathWs, actualQuestion] = stringTrimStart(cardText3); if (!settings.convertFoldersToDecks) { topicPathWithWs = new TopicPathWithWs(topicPath, preTopicPathWs, postTopicPathWs); } } [actualQuestion, blockId] = this.extractObsidianBlockId(actualQuestion); return [topicPathWithWs, actualQuestion, blockId]; } static extractObsidianBlockId(text) { let question = text; let blockId = null; const match2 = text.match(OBSIDIAN_BLOCK_ID_ENDOFLINE_REGEX); if (match2) { blockId = match2[0].trim(); const newLength = question.length - blockId.length; question = question.substring(0, newLength).trimEnd(); } return [question, blockId]; } formatTopicAndQuestion() { let result = ""; if (this.topicPathWithWs) { result += this.topicPathWithWs.formatWithWs(); } result += this.actualQuestion; return result; } }; var Question = class _Question { get questionType() { return this.parsedQuestionInfo.cardType; } get lineNo() { return this.parsedQuestionInfo.firstLineNum; } constructor(init) { Object.assign(this, init); } getHtmlCommentSeparator(settings) { const sep2 = this.isCardCommentsOnSameLine(settings) ? " " : "\n"; return sep2; } isCardCommentsOnSameLine(settings) { let result = settings.cardCommentOnSameLine; if (this.questionText.endsWithCodeBlock()) { result = false; } return result; } setCardList(cards) { this.cards = cards; this.cards.forEach((card) => card.question = this); } formatForNote(settings) { let result = this.questionText.formatTopicAndQuestion(); const blockId = this.questionText.obsidianBlockId; const hasSchedule = this.cards.some((card) => card.hasSchedule); if (hasSchedule) { result = result.trimEnd(); const scheduleHtml = DataStoreAlgorithm.getInstance().questionFormatScheduleAsHtmlComment(this); if (blockId) { if (this.isCardCommentsOnSameLine(settings)) result += ` ${scheduleHtml} ${blockId}`; else result += ` ${blockId} ${scheduleHtml}`; } else { result += this.getHtmlCommentSeparator(settings) + scheduleHtml; } } else { if (blockId) result += ` ${blockId}`; } return result; } updateQuestionWithinNoteText(noteText, settings) { const originalText = this.questionText.original; const replacementText = this.formatForNote(settings); let newText = MultiLineTextFinder.findAndReplace(noteText, originalText, replacementText); if (newText) { this.questionText = QuestionText.create( replacementText, this.questionText.textDirection, settings ); } else { console.error( `updateQuestionText: Text not found: ${originalText.substring( 0, 100 )} in note: ${noteText.substring(0, 100)}` ); newText = noteText; } return newText; } async writeQuestion(settings) { const fileText = await this.note.file.read(); const newText = this.updateQuestionWithinNoteText(fileText, settings); await this.note.file.write(newText); this.hasChanged = false; } formatTopicPathList() { return this.topicPathList.format("|"); } static Create(settings, parsedQuestionInfo, noteTopicPathList, textDirection, context) { const hasEditLaterTag = parsedQuestionInfo.text.includes(settings.editLaterTag); const questionText = QuestionText.create( parsedQuestionInfo.text, textDirection, settings ); let topicPathList = noteTopicPathList; if (questionText.topicPathWithWs) { topicPathList = new TopicPathList([questionText.topicPathWithWs.topicPath]); } const result = new _Question({ parsedQuestionInfo, topicPathList, questionText, hasEditLaterTag, questionContext: context, cards: null, hasChanged: false }); return result; } }; // src/parser.ts var debugParser = false; function setDebugParser(value) { debugParser = value; } var ParsedQuestionInfo = class { constructor(cardType, text, firstLineNum, lastLineNum) { this.cardType = cardType; this.text = text; this.firstLineNum = firstLineNum; this.lastLineNum = lastLineNum; } isQuestionLineNum(lineNum) { return lineNum >= this.firstLineNum && lineNum <= this.lastLineNum; } }; function markerInsideCodeBlock(text, marker, markerIndex) { let goingBack = markerIndex - 1, goingForward = markerIndex + marker.length; let backTicksBefore = 0, backTicksAfter = 0; while (goingBack >= 0) { if (text[goingBack] === "`") backTicksBefore++; goingBack--; } while (goingForward < text.length) { if (text[goingForward] === "`") backTicksAfter++; goingForward++; } return backTicksBefore % 2 === 1 && backTicksAfter % 2 === 1; } function hasInlineMarker(text, marker) { if (marker.length == 0) return false; const markerIdx = text.indexOf(marker); if (markerIdx === -1) return false; return !markerInsideCodeBlock(text, marker, markerIdx); } function parse(text, options) { if (debugParser) { console.log("Text to parse:\n<<<" + text + ">>>"); } const inlineSeparators = [ { separator: options.singleLineCardSeparator, type: 0 /* SingleLineBasic */ }, { separator: options.singleLineReversedCardSeparator, type: 1 /* SingleLineReversed */ } ]; inlineSeparators.sort((a2, b2) => b2.separator.length - a2.separator.length); const cards = []; let cardText = ""; let cardType = null; let firstLineNo = 0, lastLineNo = 0; const clozecrafter = new import_clozecraft.ClozeCrafter(options.clozePatterns); const lines = text.replaceAll("\r\n", "\n").split("\n"); for (let i2 = 0; i2 < lines.length; i2++) { const currentLine = lines[i2], currentTrimmed = lines[i2].trim(); if (currentLine.startsWith("")) i2++; i2++; continue; } const isEmptyLine = currentTrimmed.length == 0; const hasMultilineCardEndMarker = options.multilineCardEndMarker && currentTrimmed == options.multilineCardEndMarker; if ( // We've probably reached the end of a card isEmptyLine && !options.multilineCardEndMarker || // Empty line & we're not picking up any card isEmptyLine && cardType == null || // We've reached the end of a multi line card & // we're using custom end markers hasMultilineCardEndMarker ) { if (cardType) { lastLineNo = i2 - 1; cards.push( new ParsedQuestionInfo(cardType, cardText.trimEnd(), firstLineNo, lastLineNo) ); cardType = null; } cardText = ""; firstLineNo = i2 + 1; continue; } if (cardText.length > 0) { cardText += "\n"; } cardText += currentLine.trimEnd(); for (const { separator, type } of inlineSeparators) { if (hasInlineMarker(currentLine, separator)) { cardType = type; break; } } if (cardType == 0 /* SingleLineBasic */ || cardType == 1 /* SingleLineReversed */) { cardText = currentLine; firstLineNo = i2; if (i2 + 1 < lines.length && lines[i2 + 1].startsWith("/gm, ""); } async questionWriteSchedule(question) { await this.questionWrite(question); } async questionWrite(question) { const fileText = await question.note.file.read(); const newText = question.updateQuestionWithinNoteText(fileText, this.settings); await question.note.file.write(newText); question.hasChanged = false; } }; // src/gui/flashcard-modal.tsx var import_obsidian7 = require("obsidian"); // src/gui/deck-list-view.tsx var import_vhtml = __toESM(require_vhtml()); var DeckListView = class { constructor(plugin, settings, reviewSequencer, contentEl, startReviewOfDeck) { this.plugin = plugin; this.settings = settings; this.reviewSequencer = reviewSequencer; this.modalContentEl = contentEl; this.startReviewOfDeck = startReviewOfDeck; this.init(); } /** * Initializes all static elements in the DeckListView */ init() { this.view = this.modalContentEl.createDiv(); this.view.addClasses(["sr-deck-list", "sr-is-hidden"]); this.header = this.view.createDiv(); this.header.addClass("sr-header"); this.title = this.header.createDiv(); this.title.addClass("sr-title"); this.title.setText(t("DECKS")); this.stats = this.header.createDiv(); this.stats.addClass("sr-header-stats-container"); this._createHeaderStats(); this.content = this.view.createDiv(); this.content.addClass("sr-content"); } /** * Shows the DeckListView & rerenders dynamic elements */ show() { this.mode = 0 /* DecksList */; this._createHeaderStats(); this.content.empty(); for (const deck of this.reviewSequencer.originalDeckTree.subdecks) { this._createTree(deck, this.content); } if (this.view.hasClass("sr-is-hidden")) { this.view.removeClass("sr-is-hidden"); } } /** * Hides the DeckListView */ hide() { if (!this.view.hasClass("sr-is-hidden")) { this.view.addClass("sr-is-hidden"); } } /** * Closes the DeckListView */ close() { this.hide(); } // -> Header _createHeaderStats() { const statistics = this.reviewSequencer.getDeckStats(TopicPath.emptyPath); this.stats.empty(); this._createHeaderStatsContainer(t("DUE_CARDS"), statistics.dueCount, "sr-bg-green"); this._createHeaderStatsContainer(t("NEW_CARDS"), statistics.newCount, "sr-bg-blue"); this._createHeaderStatsContainer(t("TOTAL_CARDS"), statistics.totalCount, "sr-bg-red"); } _createHeaderStatsContainer(statsLable, statsNumber, statsClass) { const statsContainer = this.stats.createDiv(); statsContainer.ariaLabel = statsLable; statsContainer.addClasses([ "tag-pane-tag-count", "tree-item-flair", "sr-header-stats-count", statsClass ]); const lable = statsContainer.createDiv(); lable.setText(statsLable + ":"); const number = statsContainer.createDiv(); number.setText(statsNumber.toString()); } // -> Tree content _createTree(deck, container) { const deckTree = container.createDiv("tree-item sr-tree-item-container"); const deckTreeSelf = deckTree.createDiv( "tree-item-self tag-pane-tag is-clickable sr-tree-item-row" ); const shouldBeInitiallyExpanded = this.settings.initiallyExpandAllSubdecksInTree; let collapsed = !shouldBeInitiallyExpanded; let collapseIconEl = null; if (deck.subdecks.length > 0) { collapseIconEl = deckTreeSelf.createDiv("tree-item-icon collapse-icon"); collapseIconEl.innerHTML = COLLAPSE_ICON; collapseIconEl.childNodes[0].style.transform = collapsed ? "rotate(-90deg)" : ""; } const deckTreeInner = deckTreeSelf.createDiv("tree-item-inner"); const deckTreeInnerText = deckTreeInner.createDiv("tag-pane-tag-text"); deckTreeInnerText.innerHTML += /* @__PURE__ */ (0, import_vhtml.default)("span", { class: "tag-pane-tag-self" }, deck.deckName); const deckTreeOuter = deckTreeSelf.createDiv(); deckTreeOuter.addClasses(["tree-item-flair-outer", "sr-tree-stats-container"]); const deckStats = this.reviewSequencer.getDeckStats(deck.getTopicPath()); this._createStats(deckStats, deckTreeOuter); const deckTreeChildren = deckTree.createDiv("tree-item-children"); deckTreeChildren.style.display = collapsed ? "none" : "block"; if (deck.subdecks.length > 0) { collapseIconEl.addEventListener("click", (e2) => { if (collapsed) { collapseIconEl.childNodes[0].style.transform = ""; deckTreeChildren.style.display = "block"; } else { collapseIconEl.childNodes[0].style.transform = "rotate(-90deg)"; deckTreeChildren.style.display = "none"; } e2.stopPropagation(); collapsed = !collapsed; }); } deckTreeSelf.addEventListener("click", () => { this.startReviewOfDeck(deck); }); for (const subdeck of deck.subdecks) { this._createTree(subdeck, deckTreeChildren); } } _createStats(statistics, statsWrapper) { statsWrapper.empty(); this._createStatsContainer( t("DUE_CARDS"), statistics.dueCount, "sr-bg-green", statsWrapper ); this._createStatsContainer(t("NEW_CARDS"), statistics.newCount, "sr-bg-blue", statsWrapper); this._createStatsContainer( t("TOTAL_CARDS"), statistics.totalCount, "sr-bg-red", statsWrapper ); } _createStatsContainer(statsLable, statsNumber, statsClass, statsWrapper) { const statsContainer = statsWrapper.createDiv(); statsContainer.ariaLabel = statsLable; statsContainer.addClasses([ "tag-pane-tag-count", "tree-item-flair", "sr-tree-stats-count", statsClass ]); statsContainer.setText(statsNumber.toString()); } }; // src/gui/edit-modal.tsx var import_obsidian4 = require("obsidian"); var FlashcardEditModal = class _FlashcardEditModal extends import_obsidian4.Modal { constructor(app, existingText, textDirection) { super(app); this.didSaveChanges = false; // -> Functions & helpers this.saveClickCallback = (_2) => this.save(); this.cancelClickCallback = (_2) => this.cancel(); this.saveOnEnterCallback = (evt) => { if ((evt.ctrlKey || evt.metaKey) && evt.key === "Enter") { evt.preventDefault(); this.save(); } }; this.modalText = existingText; this.changedText = existingText; this.textDirection = textDirection; this.waitForClose = new Promise((resolve2, reject) => { this.resolvePromise = resolve2; this.rejectPromise = reject; }); this.modalEl.addClasses(["sr-modal", "sr-edit-modal"]); this.init(); this.open(); } static Prompt(app, placeholder, textDirection) { const newPromptModal = new _FlashcardEditModal(app, placeholder, textDirection); return newPromptModal.waitForClose; } /** * Initializes all components of the EditModal */ init() { var _a; this.contentEl.empty(); this.contentEl.addClass("sr-edit-view"); this.title = this.contentEl.createDiv(); this.title.setText(t("EDIT_CARD")); this.title.addClass("sr-title"); this.textArea = this.contentEl.createEl("textarea"); this.textArea.addClass("sr-input"); this.textArea.setText((_a = this.modalText) != null ? _a : ""); this.textArea.addEventListener("keydown", this.saveOnEnterCallback); if (this.textDirection == 2 /* Rtl */) { this.textArea.setAttribute("dir", "rtl"); } this._createResponse(this.contentEl); } /** * Opens the EditModal */ onOpen() { super.onOpen(); this.textArea.focus(); } /** * Closes the EditModal */ onClose() { super.onClose(); this.resolveInput(); this.removeInputListener(); } save() { this.didSaveChanges = true; this.changedText = this.textArea.value; this.close(); } cancel() { this.close(); } resolveInput() { if (!this.didSaveChanges) this.rejectPromise(t("NO_INPUT")); else this.resolvePromise(this.changedText); } removeInputListener() { this.textArea.removeEventListener("keydown", this.saveOnEnterCallback); } // -> Response section _createResponseButton(container, text, colorClass, callback2) { const button = container.createEl("button"); button.addClasses(["sr-response-button", colorClass]); button.setText(text); button.addEventListener("click", callback2); } _createResponse(mainContentContainer) { const response = mainContentContainer.createDiv(); response.addClass("sr-response"); this._createResponseButton(response, t("CANCEL"), "sr-bg-red", this.cancelClickCallback); this._createResponseButton(response, "", "sr-spacer", () => { }); this._createResponseButton(response, t("SAVE"), "sr-bg-green", this.saveClickCallback); } }; // src/gui/flashcard-review-view.tsx var import_moment4 = __toESM(require_moment()); var import_obsidian6 = require("obsidian"); // src/utils/renderers.ts var import_obsidian5 = require("obsidian"); var RenderMarkdownWrapper = class { constructor(app, plugin, notePath) { this.app = app; this.notePath = notePath; this.plugin = plugin; } // slightly modified version of the renderMarkdown function in // https://github.com/mgmeyers/obsidian-kanban/blob/main/src/KanbanView.tsx async renderMarkdownWrapper(markdownString, containerEl, textDirection, recursiveDepth = 0) { if (recursiveDepth > 4) return; let el; if (textDirection == 2 /* Rtl */) { el = containerEl.createDiv(); el.setAttribute("dir", "rtl"); } else el = containerEl; import_obsidian5.MarkdownRenderer.render(this.app, markdownString, el, this.notePath, this.plugin); el.findAll(".internal-embed").forEach((el2) => { const link2 = this.parseLink(el2.getAttribute("src")); if (!link2.target) { el2.innerText = link2.text; } else if (link2.target instanceof import_obsidian5.TFile) { if (link2.target.extension !== "md") { this.embedMediaFile(el2, link2.target); } else { } } }); } parseLink(src) { const linkComponentsRegex = /^(? [^#^]+)?(?:#(?!\^)(? .+)|#\^(? .+)|#)?$/; const matched = typeof src === "string" && src.match(linkComponentsRegex); const file = matched.groups.file || this.notePath; const target = this.plugin.app.metadataCache.getFirstLinkpathDest(file, this.notePath); return { text: matched[0], file: matched.groups.file, heading: matched.groups.heading, blockId: matched.groups.blockId, target }; } embedMediaFile(el, target) { el.innerText = ""; if (IMAGE_FORMATS.includes(target.extension)) { el.createEl( "img", { attr: { src: this.plugin.app.vault.getResourcePath(target) } }, (img) => { if (el.hasAttribute("width")) img.setAttribute("width", el.getAttribute("width")); else img.setAttribute("width", "100%"); if (el.hasAttribute("alt")) img.setAttribute("alt", el.getAttribute("alt")); el.addEventListener( "click", (ev) => ev.target.style.minWidth = ev.target.style.minWidth === "100%" ? null : "100%" ); } ); el.addClasses(["image-embed", "is-loaded"]); } else if (AUDIO_FORMATS.includes(target.extension) || VIDEO_FORMATS.includes(target.extension)) { el.createEl( AUDIO_FORMATS.includes(target.extension) ? "audio" : "video", { attr: { controls: "", src: this.plugin.app.vault.getResourcePath(target) } }, (audio) => { if (el.hasAttribute("alt")) audio.setAttribute("alt", el.getAttribute("alt")); } ); el.addClasses(["media-embed", "is-loaded"]); } else { el.innerText = target.path; } } }; // src/gui/flashcard-review-view.tsx var FlashcardReviewView = class { constructor(app, plugin, settings, reviewSequencer, reviewMode, contentEl, modalEl, backClickHandler, editClickHandler) { this._keydownHandler = (e2) => { if (document.activeElement.nodeName === "TEXTAREA" || this.mode === 3 /* Closed */) { return; } const consumeKeyEvent = () => { e2.preventDefault(); e2.stopPropagation(); }; switch (e2.code) { case "KeyS": this._skipCurrentCard(); consumeKeyEvent(); break; case "Space": if (this.mode === 1 /* Front */) { this._showAnswer(); consumeKeyEvent(); } else if (this.mode === 2 /* Back */) { this._processReview(1 /* Good */); consumeKeyEvent(); } break; case "Enter": case "NumpadEnter": if (this.mode !== 1 /* Front */) { break; } this._showAnswer(); consumeKeyEvent(); break; case "Numpad1": case "Digit1": if (this.mode !== 2 /* Back */) { break; } this._processReview(2 /* Hard */); consumeKeyEvent(); break; case "Numpad2": case "Digit2": if (this.mode !== 2 /* Back */) { break; } this._processReview(1 /* Good */); consumeKeyEvent(); break; case "Numpad3": case "Digit3": if (this.mode !== 2 /* Back */) { break; } this._processReview(0 /* Easy */); consumeKeyEvent(); break; case "Numpad0": case "Digit0": if (this.mode !== 2 /* Back */) { break; } this._processReview(3 /* Reset */); consumeKeyEvent(); break; default: break; } }; this.app = app; this.plugin = plugin; this.settings = settings; this.reviewSequencer = reviewSequencer; this.reviewMode = reviewMode; this.backClickHandler = backClickHandler; this.editClickHandler = editClickHandler; this.modalContentEl = contentEl; this.modalEl = modalEl; this.chosenDeck = null; this.init(); } /** * Initializes all static elements in the FlashcardView */ init() { this._createBackButton(); this.view = this.modalContentEl.createDiv(); this.view.addClasses(["sr-flashcard", "sr-is-hidden"]); this.header = this.view.createDiv(); this.header.addClass("sr-header"); this.titleWrapper = this.header.createDiv(); this.titleWrapper.addClass("sr-title-wrapper"); this.title = this.titleWrapper.createDiv(); this.title.addClass("sr-title"); this.subTitle = this.titleWrapper.createDiv(); this.subTitle.addClasses(["sr-sub-title", "sr-is-hidden"]); this.controls = this.header.createDiv(); this.controls.addClass("sr-controls"); this._createCardControls(); if (this.settings.showContextInCards) { this.context = this.view.createDiv(); this.context.addClass("sr-context"); } this.content = this.view.createDiv(); this.content.addClass("sr-content"); this.response = this.view.createDiv(); this.response.addClass("sr-response"); this._createResponseButtons(); } /** * Shows the FlashcardView if it is hidden */ async show(chosenDeck) { if (!this.view.hasClass("sr-is-hidden")) { return; } this.chosenDeck = chosenDeck; await this._drawContent(); this.view.removeClass("sr-is-hidden"); this.backButton.removeClass("sr-is-hidden"); document.addEventListener("keydown", this._keydownHandler); } /** * Refreshes all dynamic elements */ async refresh() { await this._drawContent(); } /** * Hides the FlashcardView if it is visible */ hide() { if (this.view.hasClass("sr-is-hidden")) { return; } document.removeEventListener("keydown", this._keydownHandler); this.view.addClass("sr-is-hidden"); this.backButton.addClass("sr-is-hidden"); } /** * Closes the FlashcardView */ close() { this.hide(); document.removeEventListener("keydown", this._keydownHandler); } // #region -> Functions & helpers async _drawContent() { this.mode = 1 /* Front */; const currentDeck = this.reviewSequencer.currentDeck; this._setTitle(this.chosenDeck); this._setSubTitle(this.chosenDeck, currentDeck); this.resetButton.disabled = true; if (this.settings.showContextInCards) { this.context.setText( this._formatQuestionContextText(this._currentQuestion.questionContext) ); } this.content.empty(); const wrapper = new RenderMarkdownWrapper( this.app, this.plugin, this._currentNote.filePath ); await wrapper.renderMarkdownWrapper( this._currentCard.front.trimStart(), this.content, this._currentQuestion.questionText.textDirection ); this.content.scrollTop = 0; this._resetResponseButtons(); } _displayCurrentCardInfoNotice() { var _a; const schedule = this._currentCard.scheduleInfo; const currentEaseStr = t("CURRENT_EASE_HELP_TEXT") + ((_a = schedule == null ? void 0 : schedule.latestEase) != null ? _a : t("NEW")); const currentIntervalStr = t("CURRENT_INTERVAL_HELP_TEXT") + textInterval(schedule == null ? void 0 : schedule.interval, false); const generatedFromStr = t("CARD_GENERATED_FROM", { notePath: this._currentQuestion.note.filePath }); new import_obsidian6.Notice(currentEaseStr + "\n" + currentIntervalStr + "\n" + generatedFromStr); } get _currentCard() { return this.reviewSequencer.currentCard; } get _currentQuestion() { return this.reviewSequencer.currentQuestion; } get _currentNote() { return this.reviewSequencer.currentNote; } _showAnswer() { const timeNow = (0, import_moment4.now)(); if (this.lastPressed && timeNow - this.lastPressed < this.plugin.data.settings.reviewButtonDelay) { return; } this.lastPressed = timeNow; this.mode = 2 /* Back */; this.resetButton.disabled = false; if (this._currentQuestion.questionType !== 4 /* Cloze */) { const hr = document.createElement("hr"); hr.addClass("sr-card-divide"); this.content.appendChild(hr); } else { this.content.empty(); } const wrapper = new RenderMarkdownWrapper( this.app, this.plugin, this._currentNote.filePath ); wrapper.renderMarkdownWrapper( this._currentCard.back, this.content, this._currentQuestion.questionText.textDirection ); this.answerButton.addClass("sr-is-hidden"); this.hardButton.removeClass("sr-is-hidden"); this.easyButton.removeClass("sr-is-hidden"); if (this.reviewMode === 0 /* Cram */) { this.response.addClass("is-cram"); this.hardButton.setText(`${this.settings.flashcardHardText}`); this.easyButton.setText(`${this.settings.flashcardEasyText}`); } else { this.goodButton.removeClass("sr-is-hidden"); this._setupEaseButton( this.hardButton, this.settings.flashcardHardText, 2 /* Hard */ ); this._setupEaseButton( this.goodButton, this.settings.flashcardGoodText, 1 /* Good */ ); this._setupEaseButton( this.easyButton, this.settings.flashcardEasyText, 0 /* Easy */ ); } } async _processReview(response) { const timeNow = (0, import_moment4.now)(); if (this.lastPressed && timeNow - this.lastPressed < this.plugin.data.settings.reviewButtonDelay) { return; } this.lastPressed = timeNow; await this.reviewSequencer.processReview(response); await this._handleSkipCard(); } async _skipCurrentCard() { this.reviewSequencer.skipCurrentCard(); await this._handleSkipCard(); } async _handleSkipCard() { if (this._currentCard != null) await this.refresh(); else this.backClickHandler(); } _formatQuestionContextText(questionContext) { const separator = " > "; let result = this._currentNote.file.basename; questionContext.forEach((context) => { if (context.startsWith("[[") && context.endsWith("]]")) { context = context.replace("[[", "").replace("]]", ""); if (context.contains("|")) { context = context.split("|")[1]; } } result += separator + context; }); return result; } // -> Header _createBackButton() { this.backButton = this.modalEl.createDiv(); this.backButton.addClasses(["sr-back-button", "sr-is-hidden"]); (0, import_obsidian6.setIcon)(this.backButton, "arrow-left"); this.backButton.setAttribute("aria-label", t("BACK")); this.backButton.addEventListener("click", () => { this.backClickHandler(); }); } _setTitle(deck) { let text = deck.deckName; const deckStats = this.reviewSequencer.getDeckStats(deck.getTopicPath()); const cardsInQueue = deckStats.dueCount + deckStats.newCount; text += `: ${cardsInQueue}`; this.title.setText(text); } _setSubTitle(chosenDeck, currentDeck) { if (chosenDeck.subdecks.length === 0) { if (!this.subTitle.hasClass("sr-is-hidden")) { this.subTitle.addClass("sr-is-hidden"); } return; } if (this.subTitle.hasClass("sr-is-hidden")) { this.subTitle.removeClass("sr-is-hidden"); } let text = `${currentDeck.deckName}`; const isRandomMode = this.settings.flashcardCardOrder === "EveryCardRandomDeckAndCard"; if (!isRandomMode) { const subDecksWithCardsInQueue = chosenDeck.subdecks.filter((subDeck) => { const deckStats = this.reviewSequencer.getDeckStats(subDeck.getTopicPath()); return deckStats.dueCount + deckStats.newCount > 0; }); text = `${t("DECKS")}: ${subDecksWithCardsInQueue.length} | ${text}`; text += `: ${currentDeck.getCardCount(2 /* All */, false)}`; } this.subTitle.setText(text); } // -> Controls _createCardControls() { this._createEditButton(); this._createResetButton(); this._createCardInfoButton(); this._createSkipButton(); } _createEditButton() { this.editButton = this.controls.createEl("button"); this.editButton.addClasses(["sr-button", "sr-edit-button"]); (0, import_obsidian6.setIcon)(this.editButton, "edit"); this.editButton.setAttribute("aria-label", t("EDIT_CARD")); this.editButton.addEventListener("click", async () => { this.editClickHandler(); }); } _createResetButton() { this.resetButton = this.controls.createEl("button"); this.resetButton.addClasses(["sr-button", "sr-reset-button"]); (0, import_obsidian6.setIcon)(this.resetButton, "refresh-cw"); this.resetButton.setAttribute("aria-label", t("RESET_CARD_PROGRESS")); this.resetButton.addEventListener("click", () => { this._processReview(3 /* Reset */); }); } _createCardInfoButton() { this.infoButton = this.controls.createEl("button"); this.infoButton.addClasses(["sr-button", "sr-info-button"]); (0, import_obsidian6.setIcon)(this.infoButton, "info"); this.infoButton.setAttribute("aria-label", "View Card Info"); this.infoButton.addEventListener("click", async () => { this._displayCurrentCardInfoNotice(); }); } _createSkipButton() { this.skipButton = this.controls.createEl("button"); this.skipButton.addClasses(["sr-button", "sr-skip-button"]); (0, import_obsidian6.setIcon)(this.skipButton, "chevrons-right"); this.skipButton.setAttribute("aria-label", t("SKIP")); this.skipButton.addEventListener("click", () => { this._skipCurrentCard(); }); } // -> Response _createResponseButtons() { this._createShowAnswerButton(); this._createHardButton(); this._createGoodButton(); this._createEasyButton(); } _resetResponseButtons() { this.answerButton.removeClass("sr-is-hidden"); this.hardButton.addClass("sr-is-hidden"); this.goodButton.addClass("sr-is-hidden"); this.easyButton.addClass("sr-is-hidden"); } _createShowAnswerButton() { this.answerButton = this.response.createEl("button"); this.answerButton.addClasses(["sr-response-button", "sr-show-answer-button", "sr-bg-blue"]); this.answerButton.setText(t("SHOW_ANSWER")); this.answerButton.addEventListener("click", () => { this._showAnswer(); }); } _createHardButton() { this.hardButton = this.response.createEl("button"); this.hardButton.addClasses([ "sr-response-button", "sr-hard-button", "sr-bg-red", "sr-is-hidden" ]); this.hardButton.setText(this.settings.flashcardHardText); this.hardButton.addEventListener("click", () => { this._processReview(2 /* Hard */); }); } _createGoodButton() { this.goodButton = this.response.createEl("button"); this.goodButton.addClasses([ "sr-response-button", "sr-good-button", "sr-bg-blue", "sr-is-hidden" ]); this.goodButton.setText(this.settings.flashcardGoodText); this.goodButton.addEventListener("click", () => { this._processReview(1 /* Good */); }); } _createEasyButton() { this.easyButton = this.response.createEl("button"); this.easyButton.addClasses([ "sr-response-button", "sr-hard-button", "sr-bg-green", "sr-is-hidden" ]); this.easyButton.setText(this.settings.flashcardEasyText); this.easyButton.addEventListener("click", () => { this._processReview(0 /* Easy */); }); } _setupEaseButton(button, buttonName, reviewResponse) { const schedule = this.reviewSequencer.determineCardSchedule( reviewResponse, this._currentCard ); const interval = schedule.interval; if (this.settings.showIntervalInReviewButtons) { if (import_obsidian6.Platform.isMobile) { button.setText(textInterval(interval, true)); } else { button.setText(`${buttonName} - ${textInterval(interval, false)}`); } } else { button.setText(buttonName); } } }; // src/gui/flashcard-modal.tsx var FlashcardModal = class extends import_obsidian7.Modal { constructor(app, plugin, settings, reviewSequencer, reviewMode) { super(app); this.plugin = plugin; this.settings = settings; this.reviewSequencer = reviewSequencer; this.reviewMode = reviewMode; this.modalEl.style.height = this.settings.flashcardHeightPercentage + "%"; this.modalEl.style.maxHeight = this.settings.flashcardHeightPercentage + "%"; this.modalEl.style.width = this.settings.flashcardWidthPercentage + "%"; this.modalEl.style.maxWidth = this.settings.flashcardWidthPercentage + "%"; this.modalEl.setAttribute("id", "sr-modal"); this.contentEl.addClass("sr-modal-content"); this.deckView = new DeckListView( this.plugin, this.settings, this.reviewSequencer, this.contentEl, this._startReviewOfDeck.bind(this) ); this.flashcardView = new FlashcardReviewView( this.app, this.plugin, this.settings, this.reviewSequencer, this.reviewMode, this.contentEl, this.modalEl, this._showDecksList.bind(this), this._doEditQuestionText.bind(this) ); } onOpen() { this._showDecksList(); } onClose() { this.mode = 3 /* Closed */; this.deckView.close(); this.flashcardView.close(); } _showDecksList() { this._hideFlashcard(); this.deckView.show(); } _hideDecksList() { this.deckView.hide(); } _showFlashcard(deck) { this._hideDecksList(); this.flashcardView.show(deck); } _hideFlashcard() { this.flashcardView.hide(); } _startReviewOfDeck(deck) { this.reviewSequencer.setCurrentDeck(deck.getTopicPath()); if (this.reviewSequencer.hasCurrentCard) { this._showFlashcard(deck); } else { this._showDecksList(); } } async _doEditQuestionText() { const currentQ = this.reviewSequencer.currentQuestion; const textPrompt = currentQ.questionText.actualQuestion; const editModal = FlashcardEditModal.Prompt( this.app, textPrompt, currentQ.questionText.textDirection ); editModal.then(async (modifiedCardText) => { this.reviewSequencer.updateCurrentQuestionText(modifiedCardText); }).catch((reason) => console.log(reason)); } }; // src/gui/review-queue-list-view.tsx var import_obsidian8 = require("obsidian"); var REVIEW_QUEUE_VIEW_TYPE = "review-queue-list-view"; var ReviewQueueListView = class extends import_obsidian8.ItemView { get noteReviewQueue() { return this.nextNoteReviewHandler.noteReviewQueue; } constructor(leaf, nextNoteReviewHandler, settings) { super(leaf); this.nextNoteReviewHandler = nextNoteReviewHandler; this.settings = settings; if (this.settings.enableNoteReviewPaneOnStartup) { this.registerEvent(this.app.workspace.on("file-open", () => this.redraw())); this.registerEvent(this.app.vault.on("rename", () => this.redraw())); } } getViewType() { return REVIEW_QUEUE_VIEW_TYPE; } getDisplayText() { return t("NOTES_REVIEW_QUEUE"); } getIcon() { return "SpacedRepIcon"; } onHeaderMenu(menu) { menu.addItem((item) => { item.setTitle(t("CLOSE")).setIcon("cross").onClick(() => { this.app.workspace.detachLeavesOfType(REVIEW_QUEUE_VIEW_TYPE); }); }); } redraw() { if (!this.noteReviewQueue.reviewDecks) return; const activeFile = this.app.workspace.getActiveFile(); const rootEl = createDiv("tree-item nav-folder mod-root"); const childrenEl = rootEl.createDiv("tree-item-children nav-folder-children"); for (const [deckKey, deck] of this.noteReviewQueue.reviewDecks) { const deckCollapsed = !deck.activeFolders.has(deck.deckName); const deckFolderEl = this.createRightPaneFolder( childrenEl, deckKey, deckCollapsed, false, deck ).getElementsByClassName("tree-item-children nav-folder-children")[0]; if (deck.newNotes.length > 0) { const newNotesFolderEl = this.createRightPaneFolder( deckFolderEl, t("NEW"), !deck.activeFolders.has(t("NEW")), deckCollapsed, deck ); for (const newFile of deck.newNotes) { const fileIsOpen = activeFile && newFile.path === activeFile.path; if (fileIsOpen) { deck.activeFolders.add(deck.deckName); deck.activeFolders.add(t("NEW")); this.changeFolderFolding(newNotesFolderEl); this.changeFolderFolding(deckFolderEl); } this.createRightPaneFile( newNotesFolderEl, newFile.tfile, fileIsOpen, !deck.activeFolders.has(t("NEW")), deck ); } } if (deck.scheduledNotes.length > 0) { const now2 = Date.now(); let currUnix = -1; let schedFolderEl = null, folderTitle = ""; const maxDaysToRender = this.settings.maxNDaysNotesReviewQueue; for (const sNote of deck.scheduledNotes) { if (sNote.dueUnix != currUnix) { const nDays = Math.ceil((sNote.dueUnix - now2) / TICKS_PER_DAY); if (nDays > maxDaysToRender) { break; } if (nDays === -1) { folderTitle = t("YESTERDAY"); } else if (nDays === 0) { folderTitle = t("TODAY"); } else if (nDays === 1) { folderTitle = t("TOMORROW"); } else { folderTitle = new Date(sNote.dueUnix).toDateString(); } schedFolderEl = this.createRightPaneFolder( deckFolderEl, folderTitle, !deck.activeFolders.has(folderTitle), deckCollapsed, deck ); currUnix = sNote.dueUnix; } const fileIsOpen = activeFile && sNote.note.path === activeFile.path; if (fileIsOpen) { deck.activeFolders.add(deck.deckName); deck.activeFolders.add(folderTitle); this.changeFolderFolding(schedFolderEl); this.changeFolderFolding(deckFolderEl); } this.createRightPaneFile( schedFolderEl, sNote.note.tfile, fileIsOpen, !deck.activeFolders.has(folderTitle), deck ); } } } const contentEl = this.containerEl.children[1]; contentEl.empty(); contentEl.appendChild(rootEl); } createRightPaneFolder(parentEl, folderTitle, collapsed, hidden, deck) { const folderEl = parentEl.createDiv("tree-item nav-folder"); const folderTitleEl = folderEl.createDiv("tree-item-self nav-folder-title"); const childrenEl = folderEl.createDiv( "tree-item-children nav-folder-children" ); const collapseIconEl = folderTitleEl.createDiv( "tree-item-icon collapse-icon nav-folder-collapse-indicator" ); collapseIconEl.innerHTML = COLLAPSE_ICON; this.changeFolderFolding(folderEl, collapsed); folderTitleEl.createDiv("tree-item-inner nav-folder-title-content").setText(folderTitle); if (hidden) { folderEl.style.display = "none"; } folderTitleEl.onClickEvent(() => { this.changeFolderFolding(folderEl, !folderEl.hasClass("is-collapsed")); childrenEl.style.display = !folderEl.hasClass("is-collapsed") ? "block" : "none"; if (!folderEl.hasClass("is-collapsed")) { deck.activeFolders.delete(folderTitle); } else { deck.activeFolders.add(folderTitle); } }); return folderEl; } createRightPaneFile(folderEl, file, fileElActive, hidden, deck) { const childrenEl = folderEl.getElementsByClassName( "tree-item-children nav-folder-children" )[0]; const navFileEl = childrenEl.createDiv("nav-file"); if (hidden) { childrenEl.style.display = "none"; } const navFileTitle = navFileEl.createDiv("tree-item-self nav-file-title"); if (fileElActive) { navFileTitle.addClass("is-active"); } navFileTitle.createDiv("tree-item-inner nav-file-title-content").setText(file.basename); navFileTitle.addEventListener( "click", async (event) => { event.preventDefault(); await this.nextNoteReviewHandler.openNote(deck.deckName, file); return false; }, false ); navFileTitle.addEventListener( "contextmenu", (event) => { event.preventDefault(); const fileMenu = new import_obsidian8.Menu(); this.app.workspace.trigger("file-menu", fileMenu, file, "my-context-menu", null); fileMenu.showAtPosition({ x: event.pageX, y: event.pageY }); return false; }, false ); } changeFolderFolding(folderEl, collapsed = false) { if (collapsed) { folderEl.addClass("is-collapsed"); const collapseIconEl = folderEl.find("div.nav-folder-collapse-indicator"); collapseIconEl.addClass("is-collapsed"); } else { folderEl.removeClass("is-collapsed"); const collapseIconEl = folderEl.find("div.nav-folder-collapse-indicator"); collapseIconEl.removeClass("is-collapsed"); } } }; // src/gui/settings.tsx var import_obsidian10 = require("obsidian"); // node_modules/.pnpm/@kurkle+color@0.3.2/node_modules/@kurkle/color/dist/color.esm.js function round(v2) { return v2 + 0.5 | 0; } var lim = (v2, l2, h6) => Math.max(Math.min(v2, h6), l2); function p2b(v2) { return lim(round(v2 * 2.55), 0, 255); } function n2b(v2) { return lim(round(v2 * 255), 0, 255); } function b2n(v2) { return lim(round(v2 / 2.55) / 100, 0, 1); } function n2p(v2) { return lim(round(v2 * 100), 0, 100); } var map$1 = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }; var hex = [..."0123456789ABCDEF"]; var h1 = (b2) => hex[b2 & 15]; var h2 = (b2) => hex[(b2 & 240) >> 4] + hex[b2 & 15]; var eq = (b2) => (b2 & 240) >> 4 === (b2 & 15); var isShort = (v2) => eq(v2.r) && eq(v2.g) && eq(v2.b) && eq(v2.a); function hexParse(str) { var len = str.length; var ret; if (str[0] === "#") { if (len === 4 || len === 5) { ret = { r: 255 & map$1[str[1]] * 17, g: 255 & map$1[str[2]] * 17, b: 255 & map$1[str[3]] * 17, a: len === 5 ? map$1[str[4]] * 17 : 255 }; } else if (len === 7 || len === 9) { ret = { r: map$1[str[1]] << 4 | map$1[str[2]], g: map$1[str[3]] << 4 | map$1[str[4]], b: map$1[str[5]] << 4 | map$1[str[6]], a: len === 9 ? map$1[str[7]] << 4 | map$1[str[8]] : 255 }; } } return ret; } var alpha = (a2, f2) => a2 < 255 ? f2(a2) : ""; function hexString(v2) { var f2 = isShort(v2) ? h1 : h2; return v2 ? "#" + f2(v2.r) + f2(v2.g) + f2(v2.b) + alpha(v2.a, f2) : void 0; } var HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; function hsl2rgbn(h6, s2, l2) { const a2 = s2 * Math.min(l2, 1 - l2); const f2 = (n2, k = (n2 + h6 / 30) % 12) => l2 - a2 * Math.max(Math.min(k - 3, 9 - k, 1), -1); return [f2(0), f2(8), f2(4)]; } function hsv2rgbn(h6, s2, v2) { const f2 = (n2, k = (n2 + h6 / 60) % 6) => v2 - v2 * s2 * Math.max(Math.min(k, 4 - k, 1), 0); return [f2(5), f2(3), f2(1)]; } function hwb2rgbn(h6, w2, b2) { const rgb = hsl2rgbn(h6, 1, 0.5); let i2; if (w2 + b2 > 1) { i2 = 1 / (w2 + b2); w2 *= i2; b2 *= i2; } for (i2 = 0; i2 < 3; i2++) { rgb[i2] *= 1 - w2 - b2; rgb[i2] += w2; } return rgb; } function hueValue(r2, g2, b2, d2, max) { if (r2 === max) { return (g2 - b2) / d2 + (g2 < b2 ? 6 : 0); } if (g2 === max) { return (b2 - r2) / d2 + 2; } return (r2 - g2) / d2 + 4; } function rgb2hsl(v2) { const range = 255; const r2 = v2.r / range; const g2 = v2.g / range; const b2 = v2.b / range; const max = Math.max(r2, g2, b2); const min = Math.min(r2, g2, b2); const l2 = (max + min) / 2; let h6, s2, d2; if (max !== min) { d2 = max - min; s2 = l2 > 0.5 ? d2 / (2 - max - min) : d2 / (max + min); h6 = hueValue(r2, g2, b2, d2, max); h6 = h6 * 60 + 0.5; } return [h6 | 0, s2 || 0, l2]; } function calln(f2, a2, b2, c2) { return (Array.isArray(a2) ? f2(a2[0], a2[1], a2[2]) : f2(a2, b2, c2)).map(n2b); } function hsl2rgb(h6, s2, l2) { return calln(hsl2rgbn, h6, s2, l2); } function hwb2rgb(h6, w2, b2) { return calln(hwb2rgbn, h6, w2, b2); } function hsv2rgb(h6, s2, v2) { return calln(hsv2rgbn, h6, s2, v2); } function hue(h6) { return (h6 % 360 + 360) % 360; } function hueParse(str) { const m2 = HUE_RE.exec(str); let a2 = 255; let v2; if (!m2) { return; } if (m2[5] !== v2) { a2 = m2[6] ? p2b(+m2[5]) : n2b(+m2[5]); } const h6 = hue(+m2[2]); const p1 = +m2[3] / 100; const p2 = +m2[4] / 100; if (m2[1] === "hwb") { v2 = hwb2rgb(h6, p1, p2); } else if (m2[1] === "hsv") { v2 = hsv2rgb(h6, p1, p2); } else { v2 = hsl2rgb(h6, p1, p2); } return { r: v2[0], g: v2[1], b: v2[2], a: a2 }; } function rotate(v2, deg) { var h6 = rgb2hsl(v2); h6[0] = hue(h6[0] + deg); h6 = hsl2rgb(h6); v2.r = h6[0]; v2.g = h6[1]; v2.b = h6[2]; } function hslString(v2) { if (!v2) { return; } const a2 = rgb2hsl(v2); const h6 = a2[0]; const s2 = n2p(a2[1]); const l2 = n2p(a2[2]); return v2.a < 255 ? `hsla(${h6}, ${s2}%, ${l2}%, ${b2n(v2.a)})` : `hsl(${h6}, ${s2}%, ${l2}%)`; } var map = { x: "dark", Z: "light", Y: "re", X: "blu", W: "gr", V: "medium", U: "slate", A: "ee", T: "ol", S: "or", B: "ra", C: "lateg", D: "ights", R: "in", Q: "turquois", E: "hi", P: "ro", O: "al", N: "le", M: "de", L: "yello", F: "en", K: "ch", G: "arks", H: "ea", I: "ightg", J: "wh" }; var names$1 = { OiceXe: "f0f8ff", antiquewEte: "faebd7", aqua: "ffff", aquamarRe: "7fffd4", azuY: "f0ffff", beige: "f5f5dc", bisque: "ffe4c4", black: "0", blanKedOmond: "ffebcd", Xe: "ff", XeviTet: "8a2be2", bPwn: "a52a2a", burlywood: "deb887", caMtXe: "5f9ea0", KartYuse: "7fff00", KocTate: "d2691e", cSO: "ff7f50", cSnflowerXe: "6495ed", cSnsilk: "fff8dc", crimson: "dc143c", cyan: "ffff", xXe: "8b", xcyan: "8b8b", xgTMnPd: "b8860b", xWay: "a9a9a9", xgYF: "6400", xgYy: "a9a9a9", xkhaki: "bdb76b", xmagFta: "8b008b", xTivegYF: "556b2f", xSange: "ff8c00", xScEd: "9932cc", xYd: "8b0000", xsOmon: "e9967a", xsHgYF: "8fbc8f", xUXe: "483d8b", xUWay: "2f4f4f", xUgYy: "2f4f4f", xQe: "ced1", xviTet: "9400d3", dAppRk: "ff1493", dApskyXe: "bfff", dimWay: "696969", dimgYy: "696969", dodgerXe: "1e90ff", fiYbrick: "b22222", flSOwEte: "fffaf0", foYstWAn: "228b22", fuKsia: "ff00ff", gaRsbSo: "dcdcdc", ghostwEte: "f8f8ff", gTd: "ffd700", gTMnPd: "daa520", Way: "808080", gYF: "8000", gYFLw: "adff2f", gYy: "808080", honeyMw: "f0fff0", hotpRk: "ff69b4", RdianYd: "cd5c5c", Rdigo: "4b0082", ivSy: "fffff0", khaki: "f0e68c", lavFMr: "e6e6fa", lavFMrXsh: "fff0f5", lawngYF: "7cfc00", NmoncEffon: "fffacd", ZXe: "add8e6", ZcSO: "f08080", Zcyan: "e0ffff", ZgTMnPdLw: "fafad2", ZWay: "d3d3d3", ZgYF: "90ee90", ZgYy: "d3d3d3", ZpRk: "ffb6c1", ZsOmon: "ffa07a", ZsHgYF: "20b2aa", ZskyXe: "87cefa", ZUWay: "778899", ZUgYy: "778899", ZstAlXe: "b0c4de", ZLw: "ffffe0", lime: "ff00", limegYF: "32cd32", lRF: "faf0e6", magFta: "ff00ff", maPon: "800000", VaquamarRe: "66cdaa", VXe: "cd", VScEd: "ba55d3", VpurpN: "9370db", VsHgYF: "3cb371", VUXe: "7b68ee", VsprRggYF: "fa9a", VQe: "48d1cc", VviTetYd: "c71585", midnightXe: "191970", mRtcYam: "f5fffa", mistyPse: "ffe4e1", moccasR: "ffe4b5", navajowEte: "ffdead", navy: "80", Tdlace: "fdf5e6", Tive: "808000", TivedBb: "6b8e23", Sange: "ffa500", SangeYd: "ff4500", ScEd: "da70d6", pOegTMnPd: "eee8aa", pOegYF: "98fb98", pOeQe: "afeeee", pOeviTetYd: "db7093", papayawEp: "ffefd5", pHKpuff: "ffdab9", peru: "cd853f", pRk: "ffc0cb", plum: "dda0dd", powMrXe: "b0e0e6", purpN: "800080", YbeccapurpN: "663399", Yd: "ff0000", Psybrown: "bc8f8f", PyOXe: "4169e1", saddNbPwn: "8b4513", sOmon: "fa8072", sandybPwn: "f4a460", sHgYF: "2e8b57", sHshell: "fff5ee", siFna: "a0522d", silver: "c0c0c0", skyXe: "87ceeb", UXe: "6a5acd", UWay: "708090", UgYy: "708090", snow: "fffafa", sprRggYF: "ff7f", stAlXe: "4682b4", tan: "d2b48c", teO: "8080", tEstN: "d8bfd8", tomato: "ff6347", Qe: "40e0d0", viTet: "ee82ee", JHt: "f5deb3", wEte: "ffffff", wEtesmoke: "f5f5f5", Lw: "ffff00", LwgYF: "9acd32" }; function unpack() { const unpacked = {}; const keys = Object.keys(names$1); const tkeys = Object.keys(map); let i2, j2, k, ok, nk; for (i2 = 0; i2 < keys.length; i2++) { ok = nk = keys[i2]; for (j2 = 0; j2 < tkeys.length; j2++) { k = tkeys[j2]; nk = nk.replace(k, map[k]); } k = parseInt(names$1[ok], 16); unpacked[nk] = [k >> 16 & 255, k >> 8 & 255, k & 255]; } return unpacked; } var names; function nameParse(str) { if (!names) { names = unpack(); names.transparent = [0, 0, 0, 0]; } const a2 = names[str.toLowerCase()]; return a2 && { r: a2[0], g: a2[1], b: a2[2], a: a2.length === 4 ? a2[3] : 255 }; } var RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; function rgbParse(str) { const m2 = RGB_RE.exec(str); let a2 = 255; let r2, g2, b2; if (!m2) { return; } if (m2[7] !== r2) { const v2 = +m2[7]; a2 = m2[8] ? p2b(v2) : lim(v2 * 255, 0, 255); } r2 = +m2[1]; g2 = +m2[3]; b2 = +m2[5]; r2 = 255 & (m2[2] ? p2b(r2) : lim(r2, 0, 255)); g2 = 255 & (m2[4] ? p2b(g2) : lim(g2, 0, 255)); b2 = 255 & (m2[6] ? p2b(b2) : lim(b2, 0, 255)); return { r: r2, g: g2, b: b2, a: a2 }; } function rgbString(v2) { return v2 && (v2.a < 255 ? `rgba(${v2.r}, ${v2.g}, ${v2.b}, ${b2n(v2.a)})` : `rgb(${v2.r}, ${v2.g}, ${v2.b})`); } var to = (v2) => v2 <= 31308e-7 ? v2 * 12.92 : Math.pow(v2, 1 / 2.4) * 1.055 - 0.055; var from = (v2) => v2 <= 0.04045 ? v2 / 12.92 : Math.pow((v2 + 0.055) / 1.055, 2.4); function interpolate2(rgb1, rgb2, t3) { const r2 = from(b2n(rgb1.r)); const g2 = from(b2n(rgb1.g)); const b2 = from(b2n(rgb1.b)); return { r: n2b(to(r2 + t3 * (from(b2n(rgb2.r)) - r2))), g: n2b(to(g2 + t3 * (from(b2n(rgb2.g)) - g2))), b: n2b(to(b2 + t3 * (from(b2n(rgb2.b)) - b2))), a: rgb1.a + t3 * (rgb2.a - rgb1.a) }; } function modHSL(v2, i2, ratio) { if (v2) { let tmp = rgb2hsl(v2); tmp[i2] = Math.max(0, Math.min(tmp[i2] + tmp[i2] * ratio, i2 === 0 ? 360 : 1)); tmp = hsl2rgb(tmp); v2.r = tmp[0]; v2.g = tmp[1]; v2.b = tmp[2]; } } function clone(v2, proto) { return v2 ? Object.assign(proto || {}, v2) : v2; } function fromObject(input) { var v2 = { r: 0, g: 0, b: 0, a: 255 }; if (Array.isArray(input)) { if (input.length >= 3) { v2 = { r: input[0], g: input[1], b: input[2], a: 255 }; if (input.length > 3) { v2.a = n2b(input[3]); } } } else { v2 = clone(input, { r: 0, g: 0, b: 0, a: 1 }); v2.a = n2b(v2.a); } return v2; } function functionParse(str) { if (str.charAt(0) === "r") { return rgbParse(str); } return hueParse(str); } var Color = class _Color { constructor(input) { if (input instanceof _Color) { return input; } const type = typeof input; let v2; if (type === "object") { v2 = fromObject(input); } else if (type === "string") { v2 = hexParse(input) || nameParse(input) || functionParse(input); } this._rgb = v2; this._valid = !!v2; } get valid() { return this._valid; } get rgb() { var v2 = clone(this._rgb); if (v2) { v2.a = b2n(v2.a); } return v2; } set rgb(obj) { this._rgb = fromObject(obj); } rgbString() { return this._valid ? rgbString(this._rgb) : void 0; } hexString() { return this._valid ? hexString(this._rgb) : void 0; } hslString() { return this._valid ? hslString(this._rgb) : void 0; } mix(color2, weight) { if (color2) { const c1 = this.rgb; const c2 = color2.rgb; let w2; const p2 = weight === w2 ? 0.5 : weight; const w3 = 2 * p2 - 1; const a2 = c1.a - c2.a; const w1 = ((w3 * a2 === -1 ? w3 : (w3 + a2) / (1 + w3 * a2)) + 1) / 2; w2 = 1 - w1; c1.r = 255 & w1 * c1.r + w2 * c2.r + 0.5; c1.g = 255 & w1 * c1.g + w2 * c2.g + 0.5; c1.b = 255 & w1 * c1.b + w2 * c2.b + 0.5; c1.a = p2 * c1.a + (1 - p2) * c2.a; this.rgb = c1; } return this; } interpolate(color2, t3) { if (color2) { this._rgb = interpolate2(this._rgb, color2._rgb, t3); } return this; } clone() { return new _Color(this.rgb); } alpha(a2) { this._rgb.a = n2b(a2); return this; } clearer(ratio) { const rgb = this._rgb; rgb.a *= 1 - ratio; return this; } greyscale() { const rgb = this._rgb; const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11); rgb.r = rgb.g = rgb.b = val; return this; } opaquer(ratio) { const rgb = this._rgb; rgb.a *= 1 + ratio; return this; } negate() { const v2 = this._rgb; v2.r = 255 - v2.r; v2.g = 255 - v2.g; v2.b = 255 - v2.b; return this; } lighten(ratio) { modHSL(this._rgb, 2, ratio); return this; } darken(ratio) { modHSL(this._rgb, 2, -ratio); return this; } saturate(ratio) { modHSL(this._rgb, 1, ratio); return this; } desaturate(ratio) { modHSL(this._rgb, 1, -ratio); return this; } rotate(deg) { rotate(this._rgb, deg); return this; } }; // node_modules/.pnpm/chart.js@4.4.4/node_modules/chart.js/dist/chunks/helpers.segment.js function noop() { } var uid = /* @__PURE__ */ (() => { let id = 0; return () => id++; })(); function isNullOrUndef(value) { return value === null || typeof value === "undefined"; } function isArray(value) { if (Array.isArray && Array.isArray(value)) { return true; } const type = Object.prototype.toString.call(value); if (type.slice(0, 7) === "[object" && type.slice(-6) === "Array]") { return true; } return false; } function isObject(value) { return value !== null && Object.prototype.toString.call(value) === "[object Object]"; } function isNumberFinite(value) { return (typeof value === "number" || value instanceof Number) && isFinite(+value); } function finiteOrDefault(value, defaultValue) { return isNumberFinite(value) ? value : defaultValue; } function valueOrDefault(value, defaultValue) { return typeof value === "undefined" ? defaultValue : value; } var toPercentage = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 : +value / dimension; var toDimension = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 * dimension : +value; function callback(fn2, args, thisArg) { if (fn2 && typeof fn2.call === "function") { return fn2.apply(thisArg, args); } } function each(loopable, fn2, thisArg, reverse) { let i2, len, keys; if (isArray(loopable)) { len = loopable.length; if (reverse) { for (i2 = len - 1; i2 >= 0; i2--) { fn2.call(thisArg, loopable[i2], i2); } } else { for (i2 = 0; i2 < len; i2++) { fn2.call(thisArg, loopable[i2], i2); } } } else if (isObject(loopable)) { keys = Object.keys(loopable); len = keys.length; for (i2 = 0; i2 < len; i2++) { fn2.call(thisArg, loopable[keys[i2]], keys[i2]); } } } function _elementsEqual(a0, a1) { let i2, ilen, v0, v1; if (!a0 || !a1 || a0.length !== a1.length) { return false; } for (i2 = 0, ilen = a0.length; i2 < ilen; ++i2) { v0 = a0[i2]; v1 = a1[i2]; if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) { return false; } } return true; } function clone2(source) { if (isArray(source)) { return source.map(clone2); } if (isObject(source)) { const target = /* @__PURE__ */ Object.create(null); const keys = Object.keys(source); const klen = keys.length; let k = 0; for (; k < klen; ++k) { target[keys[k]] = clone2(source[keys[k]]); } return target; } return source; } function isValidKey(key) { return [ "__proto__", "prototype", "constructor" ].indexOf(key) === -1; } function _merger(key, target, source, options) { if (!isValidKey(key)) { return; } const tval = target[key]; const sval = source[key]; if (isObject(tval) && isObject(sval)) { merge(tval, sval, options); } else { target[key] = clone2(sval); } } function merge(target, source, options) { const sources = isArray(source) ? source : [ source ]; const ilen = sources.length; if (!isObject(target)) { return target; } options = options || {}; const merger = options.merger || _merger; let current; for (let i2 = 0; i2 < ilen; ++i2) { current = sources[i2]; if (!isObject(current)) { continue; } const keys = Object.keys(current); for (let k = 0, klen = keys.length; k < klen; ++k) { merger(keys[k], target, current, options); } } return target; } function mergeIf(target, source) { return merge(target, source, { merger: _mergerIf }); } function _mergerIf(key, target, source) { if (!isValidKey(key)) { return; } const tval = target[key]; const sval = source[key]; if (isObject(tval) && isObject(sval)) { mergeIf(tval, sval); } else if (!Object.prototype.hasOwnProperty.call(target, key)) { target[key] = clone2(sval); } } var keyResolvers = { // Chart.helpers.core resolveObjectKey should resolve empty key to root object "": (v2) => v2, // default resolvers x: (o2) => o2.x, y: (o2) => o2.y }; function _splitKey(key) { const parts = key.split("."); const keys = []; let tmp = ""; for (const part of parts) { tmp += part; if (tmp.endsWith("\\")) { tmp = tmp.slice(0, -1) + "."; } else { keys.push(tmp); tmp = ""; } } return keys; } function _getKeyResolver(key) { const keys = _splitKey(key); return (obj) => { for (const k of keys) { if (k === "") { break; } obj = obj && obj[k]; } return obj; }; } function resolveObjectKey(obj, key) { const resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key)); return resolver(obj); } function _capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } var defined = (value) => typeof value !== "undefined"; var isFunction = (value) => typeof value === "function"; var setsEqual = (a2, b2) => { if (a2.size !== b2.size) { return false; } for (const item of a2) { if (!b2.has(item)) { return false; } } return true; }; function _isClickEvent(e2) { return e2.type === "mouseup" || e2.type === "click" || e2.type === "contextmenu"; } var PI = Math.PI; var TAU = 2 * PI; var PITAU = TAU + PI; var INFINITY = Number.POSITIVE_INFINITY; var RAD_PER_DEG = PI / 180; var HALF_PI = PI / 2; var QUARTER_PI = PI / 4; var TWO_THIRDS_PI = PI * 2 / 3; var log10 = Math.log10; var sign = Math.sign; function almostEquals(x2, y2, epsilon) { return Math.abs(x2 - y2) < epsilon; } function niceNum(range) { const roundedRange = Math.round(range); range = almostEquals(range, roundedRange, range / 1e3) ? roundedRange : range; const niceRange = Math.pow(10, Math.floor(log10(range))); const fraction = range / niceRange; const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10; return niceFraction * niceRange; } function _factorize(value) { const result = []; const sqrt = Math.sqrt(value); let i2; for (i2 = 1; i2 < sqrt; i2++) { if (value % i2 === 0) { result.push(i2); result.push(value / i2); } } if (sqrt === (sqrt | 0)) { result.push(sqrt); } result.sort((a2, b2) => a2 - b2).pop(); return result; } function isNumber(n2) { return !isNaN(parseFloat(n2)) && isFinite(n2); } function almostWhole(x2, epsilon) { const rounded = Math.round(x2); return rounded - epsilon <= x2 && rounded + epsilon >= x2; } function _setMinAndMaxByKey(array, target, property) { let i2, ilen, value; for (i2 = 0, ilen = array.length; i2 < ilen; i2++) { value = array[i2][property]; if (!isNaN(value)) { target.min = Math.min(target.min, value); target.max = Math.max(target.max, value); } } } function toRadians(degrees) { return degrees * (PI / 180); } function toDegrees(radians) { return radians * (180 / PI); } function _decimalPlaces(x2) { if (!isNumberFinite(x2)) { return; } let e2 = 1; let p2 = 0; while (Math.round(x2 * e2) / e2 !== x2) { e2 *= 10; p2++; } return p2; } function getAngleFromPoint(centrePoint, anglePoint) { const distanceFromXCenter = anglePoint.x - centrePoint.x; const distanceFromYCenter = anglePoint.y - centrePoint.y; const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); if (angle < -0.5 * PI) { angle += TAU; } return { angle, distance: radialDistanceFromCenter }; } function distanceBetweenPoints(pt1, pt2) { return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); } function _normalizeAngle(a2) { return (a2 % TAU + TAU) % TAU; } function _angleBetween(angle, start, end, sameAngleIsFullCircle) { const a2 = _normalizeAngle(angle); const s2 = _normalizeAngle(start); const e2 = _normalizeAngle(end); const angleToStart = _normalizeAngle(s2 - a2); const angleToEnd = _normalizeAngle(e2 - a2); const startToAngle = _normalizeAngle(a2 - s2); const endToAngle = _normalizeAngle(a2 - e2); return a2 === s2 || a2 === e2 || sameAngleIsFullCircle && s2 === e2 || angleToStart > angleToEnd && startToAngle < endToAngle; } function _limitValue(value, min, max) { return Math.max(min, Math.min(max, value)); } function _int16Range(value) { return _limitValue(value, -32768, 32767); } function _isBetween(value, start, end, epsilon = 1e-6) { return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon; } function _lookup(table, value, cmp) { cmp = cmp || ((index) => table[index] < value); let hi = table.length - 1; let lo = 0; let mid; while (hi - lo > 1) { mid = lo + hi >> 1; if (cmp(mid)) { lo = mid; } else { hi = mid; } } return { lo, hi }; } var _lookupByKey = (table, key, value, last) => _lookup(table, value, last ? (index) => { const ti = table[index][key]; return ti < value || ti === value && table[index + 1][key] === value; } : (index) => table[index][key] < value); var _rlookupByKey = (table, key, value) => _lookup(table, value, (index) => table[index][key] >= value); function _filterBetween(values, min, max) { let start = 0; let end = values.length; while (start < end && values[start] < min) { start++; } while (end > start && values[end - 1] > max) { end--; } return start > 0 || end < values.length ? values.slice(start, end) : values; } var arrayEvents = [ "push", "pop", "shift", "splice", "unshift" ]; function listenArrayEvents(array, listener) { if (array._chartjs) { array._chartjs.listeners.push(listener); return; } Object.defineProperty(array, "_chartjs", { configurable: true, enumerable: false, value: { listeners: [ listener ] } }); arrayEvents.forEach((key) => { const method = "_onData" + _capitalize(key); const base = array[key]; Object.defineProperty(array, key, { configurable: true, enumerable: false, value(...args) { const res = base.apply(this, args); array._chartjs.listeners.forEach((object) => { if (typeof object[method] === "function") { object[method](...args); } }); return res; } }); }); } function unlistenArrayEvents(array, listener) { const stub = array._chartjs; if (!stub) { return; } const listeners = stub.listeners; const index = listeners.indexOf(listener); if (index !== -1) { listeners.splice(index, 1); } if (listeners.length > 0) { return; } arrayEvents.forEach((key) => { delete array[key]; }); delete array._chartjs; } function _arrayUnique(items) { const set2 = new Set(items); if (set2.size === items.length) { return items; } return Array.from(set2); } var requestAnimFrame = function() { if (typeof window === "undefined") { return function(callback2) { return callback2(); }; } return window.requestAnimationFrame; }(); function throttled(fn2, thisArg) { let argsToUse = []; let ticking = false; return function(...args) { argsToUse = args; if (!ticking) { ticking = true; requestAnimFrame.call(window, () => { ticking = false; fn2.apply(thisArg, argsToUse); }); } }; } function debounce(fn2, delay) { let timeout; return function(...args) { if (delay) { clearTimeout(timeout); timeout = setTimeout(fn2, delay, args); } else { fn2.apply(this, args); } return delay; }; } var _toLeftRightCenter = (align) => align === "start" ? "left" : align === "end" ? "right" : "center"; var _alignStartEnd = (align, start, end) => align === "start" ? start : align === "end" ? end : (start + end) / 2; var _textX = (align, left, right, rtl) => { const check = rtl ? "left" : "right"; return align === check ? right : align === "center" ? (left + right) / 2 : left; }; var atEdge = (t3) => t3 === 0 || t3 === 1; var elasticIn = (t3, s2, p2) => -(Math.pow(2, 10 * (t3 -= 1)) * Math.sin((t3 - s2) * TAU / p2)); var elasticOut = (t3, s2, p2) => Math.pow(2, -10 * t3) * Math.sin((t3 - s2) * TAU / p2) + 1; var effects = { linear: (t3) => t3, easeInQuad: (t3) => t3 * t3, easeOutQuad: (t3) => -t3 * (t3 - 2), easeInOutQuad: (t3) => (t3 /= 0.5) < 1 ? 0.5 * t3 * t3 : -0.5 * (--t3 * (t3 - 2) - 1), easeInCubic: (t3) => t3 * t3 * t3, easeOutCubic: (t3) => (t3 -= 1) * t3 * t3 + 1, easeInOutCubic: (t3) => (t3 /= 0.5) < 1 ? 0.5 * t3 * t3 * t3 : 0.5 * ((t3 -= 2) * t3 * t3 + 2), easeInQuart: (t3) => t3 * t3 * t3 * t3, easeOutQuart: (t3) => -((t3 -= 1) * t3 * t3 * t3 - 1), easeInOutQuart: (t3) => (t3 /= 0.5) < 1 ? 0.5 * t3 * t3 * t3 * t3 : -0.5 * ((t3 -= 2) * t3 * t3 * t3 - 2), easeInQuint: (t3) => t3 * t3 * t3 * t3 * t3, easeOutQuint: (t3) => (t3 -= 1) * t3 * t3 * t3 * t3 + 1, easeInOutQuint: (t3) => (t3 /= 0.5) < 1 ? 0.5 * t3 * t3 * t3 * t3 * t3 : 0.5 * ((t3 -= 2) * t3 * t3 * t3 * t3 + 2), easeInSine: (t3) => -Math.cos(t3 * HALF_PI) + 1, easeOutSine: (t3) => Math.sin(t3 * HALF_PI), easeInOutSine: (t3) => -0.5 * (Math.cos(PI * t3) - 1), easeInExpo: (t3) => t3 === 0 ? 0 : Math.pow(2, 10 * (t3 - 1)), easeOutExpo: (t3) => t3 === 1 ? 1 : -Math.pow(2, -10 * t3) + 1, easeInOutExpo: (t3) => atEdge(t3) ? t3 : t3 < 0.5 ? 0.5 * Math.pow(2, 10 * (t3 * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t3 * 2 - 1)) + 2), easeInCirc: (t3) => t3 >= 1 ? t3 : -(Math.sqrt(1 - t3 * t3) - 1), easeOutCirc: (t3) => Math.sqrt(1 - (t3 -= 1) * t3), easeInOutCirc: (t3) => (t3 /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t3 * t3) - 1) : 0.5 * (Math.sqrt(1 - (t3 -= 2) * t3) + 1), easeInElastic: (t3) => atEdge(t3) ? t3 : elasticIn(t3, 0.075, 0.3), easeOutElastic: (t3) => atEdge(t3) ? t3 : elasticOut(t3, 0.075, 0.3), easeInOutElastic(t3) { const s2 = 0.1125; const p2 = 0.45; return atEdge(t3) ? t3 : t3 < 0.5 ? 0.5 * elasticIn(t3 * 2, s2, p2) : 0.5 + 0.5 * elasticOut(t3 * 2 - 1, s2, p2); }, easeInBack(t3) { const s2 = 1.70158; return t3 * t3 * ((s2 + 1) * t3 - s2); }, easeOutBack(t3) { const s2 = 1.70158; return (t3 -= 1) * t3 * ((s2 + 1) * t3 + s2) + 1; }, easeInOutBack(t3) { let s2 = 1.70158; if ((t3 /= 0.5) < 1) { return 0.5 * (t3 * t3 * (((s2 *= 1.525) + 1) * t3 - s2)); } return 0.5 * ((t3 -= 2) * t3 * (((s2 *= 1.525) + 1) * t3 + s2) + 2); }, easeInBounce: (t3) => 1 - effects.easeOutBounce(1 - t3), easeOutBounce(t3) { const m2 = 7.5625; const d2 = 2.75; if (t3 < 1 / d2) { return m2 * t3 * t3; } if (t3 < 2 / d2) { return m2 * (t3 -= 1.5 / d2) * t3 + 0.75; } if (t3 < 2.5 / d2) { return m2 * (t3 -= 2.25 / d2) * t3 + 0.9375; } return m2 * (t3 -= 2.625 / d2) * t3 + 0.984375; }, easeInOutBounce: (t3) => t3 < 0.5 ? effects.easeInBounce(t3 * 2) * 0.5 : effects.easeOutBounce(t3 * 2 - 1) * 0.5 + 0.5 }; function isPatternOrGradient(value) { if (value && typeof value === "object") { const type = value.toString(); return type === "[object CanvasPattern]" || type === "[object CanvasGradient]"; } return false; } function color(value) { return isPatternOrGradient(value) ? value : new Color(value); } function getHoverColor(value) { return isPatternOrGradient(value) ? value : new Color(value).saturate(0.5).darken(0.1).hexString(); } var numbers = [ "x", "y", "borderWidth", "radius", "tension" ]; var colors = [ "color", "borderColor", "backgroundColor" ]; function applyAnimationsDefaults(defaults3) { defaults3.set("animation", { delay: void 0, duration: 1e3, easing: "easeOutQuart", fn: void 0, from: void 0, loop: void 0, to: void 0, type: void 0 }); defaults3.describe("animation", { _fallback: false, _indexable: false, _scriptable: (name) => name !== "onProgress" && name !== "onComplete" && name !== "fn" }); defaults3.set("animations", { colors: { type: "color", properties: colors }, numbers: { type: "number", properties: numbers } }); defaults3.describe("animations", { _fallback: "animation" }); defaults3.set("transitions", { active: { animation: { duration: 400 } }, resize: { animation: { duration: 0 } }, show: { animations: { colors: { from: "transparent" }, visible: { type: "boolean", duration: 0 } } }, hide: { animations: { colors: { to: "transparent" }, visible: { type: "boolean", easing: "linear", fn: (v2) => v2 | 0 } } } }); } function applyLayoutsDefaults(defaults3) { defaults3.set("layout", { autoPadding: true, padding: { top: 0, right: 0, bottom: 0, left: 0 } }); } var intlCache = /* @__PURE__ */ new Map(); function getNumberFormat(locale2, options) { options = options || {}; const cacheKey = locale2 + JSON.stringify(options); let formatter = intlCache.get(cacheKey); if (!formatter) { formatter = new Intl.NumberFormat(locale2, options); intlCache.set(cacheKey, formatter); } return formatter; } function formatNumber(num, locale2, options) { return getNumberFormat(locale2, options).format(num); } var formatters = { values(value) { return isArray(value) ? value : "" + value; }, numeric(tickValue, index, ticks) { if (tickValue === 0) { return "0"; } const locale2 = this.chart.options.locale; let notation; let delta = tickValue; if (ticks.length > 1) { const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value)); if (maxTick < 1e-4 || maxTick > 1e15) { notation = "scientific"; } delta = calculateDelta(tickValue, ticks); } const logDelta = log10(Math.abs(delta)); const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0); const options = { notation, minimumFractionDigits: numDecimal, maximumFractionDigits: numDecimal }; Object.assign(options, this.options.ticks.format); return formatNumber(tickValue, locale2, options); }, logarithmic(tickValue, index, ticks) { if (tickValue === 0) { return "0"; } const remain = ticks[index].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue))); if ([ 1, 2, 3, 5, 10, 15 ].includes(remain) || index > 0.8 * ticks.length) { return formatters.numeric.call(this, tickValue, index, ticks); } return ""; } }; function calculateDelta(tickValue, ticks) { let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value; if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) { delta = tickValue - Math.floor(tickValue); } return delta; } var Ticks = { formatters }; function applyScaleDefaults(defaults3) { defaults3.set("scale", { display: true, offset: false, reverse: false, beginAtZero: false, bounds: "ticks", clip: true, grace: 0, grid: { display: true, lineWidth: 1, drawOnChartArea: true, drawTicks: true, tickLength: 8, tickWidth: (_ctx, options) => options.lineWidth, tickColor: (_ctx, options) => options.color, offset: false }, border: { display: true, dash: [], dashOffset: 0, width: 1 }, title: { display: false, text: "", padding: { top: 4, bottom: 4 } }, ticks: { minRotation: 0, maxRotation: 50, mirror: false, textStrokeWidth: 0, textStrokeColor: "", padding: 3, display: true, autoSkip: true, autoSkipPadding: 3, labelOffset: 0, callback: Ticks.formatters.values, minor: {}, major: {}, align: "center", crossAlign: "near", showLabelBackdrop: false, backdropColor: "rgba(255, 255, 255, 0.75)", backdropPadding: 2 } }); defaults3.route("scale.ticks", "color", "", "color"); defaults3.route("scale.grid", "color", "", "borderColor"); defaults3.route("scale.border", "color", "", "borderColor"); defaults3.route("scale.title", "color", "", "color"); defaults3.describe("scale", { _fallback: false, _scriptable: (name) => !name.startsWith("before") && !name.startsWith("after") && name !== "callback" && name !== "parser", _indexable: (name) => name !== "borderDash" && name !== "tickBorderDash" && name !== "dash" }); defaults3.describe("scales", { _fallback: "scale" }); defaults3.describe("scale.ticks", { _scriptable: (name) => name !== "backdropPadding" && name !== "callback", _indexable: (name) => name !== "backdropPadding" }); } var overrides = /* @__PURE__ */ Object.create(null); var descriptors = /* @__PURE__ */ Object.create(null); function getScope$1(node, key) { if (!key) { return node; } const keys = key.split("."); for (let i2 = 0, n2 = keys.length; i2 < n2; ++i2) { const k = keys[i2]; node = node[k] || (node[k] = /* @__PURE__ */ Object.create(null)); } return node; } function set(root, scope, values) { if (typeof scope === "string") { return merge(getScope$1(root, scope), values); } return merge(getScope$1(root, ""), scope); } var Defaults = class { constructor(_descriptors2, _appliers) { this.animation = void 0; this.backgroundColor = "rgba(0,0,0,0.1)"; this.borderColor = "rgba(0,0,0,0.1)"; this.color = "#666"; this.datasets = {}; this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio(); this.elements = {}; this.events = [ "mousemove", "mouseout", "click", "touchstart", "touchmove" ]; this.font = { family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", size: 12, style: "normal", lineHeight: 1.2, weight: null }; this.hover = {}; this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor); this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor); this.hoverColor = (ctx, options) => getHoverColor(options.color); this.indexAxis = "x"; this.interaction = { mode: "nearest", intersect: true, includeInvisible: false }; this.maintainAspectRatio = true; this.onHover = null; this.onClick = null; this.parsing = true; this.plugins = {}; this.responsive = true; this.scale = void 0; this.scales = {}; this.showLine = true; this.drawActiveElementsOnTop = true; this.describe(_descriptors2); this.apply(_appliers); } set(scope, values) { return set(this, scope, values); } get(scope) { return getScope$1(this, scope); } describe(scope, values) { return set(descriptors, scope, values); } override(scope, values) { return set(overrides, scope, values); } route(scope, name, targetScope, targetName) { const scopeObject = getScope$1(this, scope); const targetScopeObject = getScope$1(this, targetScope); const privateName = "_" + name; Object.defineProperties(scopeObject, { [privateName]: { value: scopeObject[name], writable: true }, [name]: { enumerable: true, get() { const local = this[privateName]; const target = targetScopeObject[targetName]; if (isObject(local)) { return Object.assign({}, target, local); } return valueOrDefault(local, target); }, set(value) { this[privateName] = value; } } }); } apply(appliers) { appliers.forEach((apply) => apply(this)); } }; var defaults2 = /* @__PURE__ */ new Defaults({ _scriptable: (name) => !name.startsWith("on"), _indexable: (name) => name !== "events", hover: { _fallback: "interaction" }, interaction: { _scriptable: false, _indexable: false } }, [ applyAnimationsDefaults, applyLayoutsDefaults, applyScaleDefaults ]); function toFontString(font) { if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { return null; } return (font.style ? font.style + " " : "") + (font.weight ? font.weight + " " : "") + font.size + "px " + font.family; } function _measureText(ctx, data, gc, longest, string) { let textWidth = data[string]; if (!textWidth) { textWidth = data[string] = ctx.measureText(string).width; gc.push(string); } if (textWidth > longest) { longest = textWidth; } return longest; } function _longestText(ctx, font, arrayOfThings, cache) { cache = cache || {}; let data = cache.data = cache.data || {}; let gc = cache.garbageCollect = cache.garbageCollect || []; if (cache.font !== font) { data = cache.data = {}; gc = cache.garbageCollect = []; cache.font = font; } ctx.save(); ctx.font = font; let longest = 0; const ilen = arrayOfThings.length; let i2, j2, jlen, thing, nestedThing; for (i2 = 0; i2 < ilen; i2++) { thing = arrayOfThings[i2]; if (thing !== void 0 && thing !== null && !isArray(thing)) { longest = _measureText(ctx, data, gc, longest, thing); } else if (isArray(thing)) { for (j2 = 0, jlen = thing.length; j2 < jlen; j2++) { nestedThing = thing[j2]; if (nestedThing !== void 0 && nestedThing !== null && !isArray(nestedThing)) { longest = _measureText(ctx, data, gc, longest, nestedThing); } } } } ctx.restore(); const gcLen = gc.length / 2; if (gcLen > arrayOfThings.length) { for (i2 = 0; i2 < gcLen; i2++) { delete data[gc[i2]]; } gc.splice(0, gcLen); } return longest; } function _alignPixel(chart, pixel, width) { const devicePixelRatio = chart.currentDevicePixelRatio; const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; } function clearCanvas(canvas, ctx) { if (!ctx && !canvas) { return; } ctx = ctx || canvas.getContext("2d"); ctx.save(); ctx.resetTransform(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.restore(); } function drawPoint(ctx, options, x2, y2) { drawPointLegend(ctx, options, x2, y2, null); } function drawPointLegend(ctx, options, x2, y2, w2) { let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW; const style = options.pointStyle; const rotation = options.rotation; const radius = options.radius; let rad = (rotation || 0) * RAD_PER_DEG; if (style && typeof style === "object") { type = style.toString(); if (type === "[object HTMLImageElement]" || type === "[object HTMLCanvasElement]") { ctx.save(); ctx.translate(x2, y2); ctx.rotate(rad); ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); ctx.restore(); return; } } if (isNaN(radius) || radius <= 0) { return; } ctx.beginPath(); switch (style) { // Default includes circle default: if (w2) { ctx.ellipse(x2, y2, w2 / 2, radius, 0, 0, TAU); } else { ctx.arc(x2, y2, radius, 0, TAU); } ctx.closePath(); break; case "triangle": width = w2 ? w2 / 2 : radius; ctx.moveTo(x2 + Math.sin(rad) * width, y2 - Math.cos(rad) * radius); rad += TWO_THIRDS_PI; ctx.lineTo(x2 + Math.sin(rad) * width, y2 - Math.cos(rad) * radius); rad += TWO_THIRDS_PI; ctx.lineTo(x2 + Math.sin(rad) * width, y2 - Math.cos(rad) * radius); ctx.closePath(); break; case "rectRounded": cornerRadius = radius * 0.516; size = radius - cornerRadius; xOffset = Math.cos(rad + QUARTER_PI) * size; xOffsetW = Math.cos(rad + QUARTER_PI) * (w2 ? w2 / 2 - cornerRadius : size); yOffset = Math.sin(rad + QUARTER_PI) * size; yOffsetW = Math.sin(rad + QUARTER_PI) * (w2 ? w2 / 2 - cornerRadius : size); ctx.arc(x2 - xOffsetW, y2 - yOffset, cornerRadius, rad - PI, rad - HALF_PI); ctx.arc(x2 + yOffsetW, y2 - xOffset, cornerRadius, rad - HALF_PI, rad); ctx.arc(x2 + xOffsetW, y2 + yOffset, cornerRadius, rad, rad + HALF_PI); ctx.arc(x2 - yOffsetW, y2 + xOffset, cornerRadius, rad + HALF_PI, rad + PI); ctx.closePath(); break; case "rect": if (!rotation) { size = Math.SQRT1_2 * radius; width = w2 ? w2 / 2 : size; ctx.rect(x2 - width, y2 - size, 2 * width, 2 * size); break; } rad += QUARTER_PI; /* falls through */ case "rectRot": xOffsetW = Math.cos(rad) * (w2 ? w2 / 2 : radius); xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; yOffsetW = Math.sin(rad) * (w2 ? w2 / 2 : radius); ctx.moveTo(x2 - xOffsetW, y2 - yOffset); ctx.lineTo(x2 + yOffsetW, y2 - xOffset); ctx.lineTo(x2 + xOffsetW, y2 + yOffset); ctx.lineTo(x2 - yOffsetW, y2 + xOffset); ctx.closePath(); break; case "crossRot": rad += QUARTER_PI; /* falls through */ case "cross": xOffsetW = Math.cos(rad) * (w2 ? w2 / 2 : radius); xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; yOffsetW = Math.sin(rad) * (w2 ? w2 / 2 : radius); ctx.moveTo(x2 - xOffsetW, y2 - yOffset); ctx.lineTo(x2 + xOffsetW, y2 + yOffset); ctx.moveTo(x2 + yOffsetW, y2 - xOffset); ctx.lineTo(x2 - yOffsetW, y2 + xOffset); break; case "star": xOffsetW = Math.cos(rad) * (w2 ? w2 / 2 : radius); xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; yOffsetW = Math.sin(rad) * (w2 ? w2 / 2 : radius); ctx.moveTo(x2 - xOffsetW, y2 - yOffset); ctx.lineTo(x2 + xOffsetW, y2 + yOffset); ctx.moveTo(x2 + yOffsetW, y2 - xOffset); ctx.lineTo(x2 - yOffsetW, y2 + xOffset); rad += QUARTER_PI; xOffsetW = Math.cos(rad) * (w2 ? w2 / 2 : radius); xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; yOffsetW = Math.sin(rad) * (w2 ? w2 / 2 : radius); ctx.moveTo(x2 - xOffsetW, y2 - yOffset); ctx.lineTo(x2 + xOffsetW, y2 + yOffset); ctx.moveTo(x2 + yOffsetW, y2 - xOffset); ctx.lineTo(x2 - yOffsetW, y2 + xOffset); break; case "line": xOffset = w2 ? w2 / 2 : Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x2 - xOffset, y2 - yOffset); ctx.lineTo(x2 + xOffset, y2 + yOffset); break; case "dash": ctx.moveTo(x2, y2); ctx.lineTo(x2 + Math.cos(rad) * (w2 ? w2 / 2 : radius), y2 + Math.sin(rad) * radius); break; case false: ctx.closePath(); break; } ctx.fill(); if (options.borderWidth > 0) { ctx.stroke(); } } function _isPointInArea(point, area, margin) { margin = margin || 0.5; return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin; } function clipArea(ctx, area) { ctx.save(); ctx.beginPath(); ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); ctx.clip(); } function unclipArea(ctx) { ctx.restore(); } function setRenderOpts(ctx, opts) { if (opts.translation) { ctx.translate(opts.translation[0], opts.translation[1]); } if (!isNullOrUndef(opts.rotation)) { ctx.rotate(opts.rotation); } if (opts.color) { ctx.fillStyle = opts.color; } if (opts.textAlign) { ctx.textAlign = opts.textAlign; } if (opts.textBaseline) { ctx.textBaseline = opts.textBaseline; } } function decorateText(ctx, x2, y2, line, opts) { if (opts.strikethrough || opts.underline) { const metrics = ctx.measureText(line); const left = x2 - metrics.actualBoundingBoxLeft; const right = x2 + metrics.actualBoundingBoxRight; const top = y2 - metrics.actualBoundingBoxAscent; const bottom = y2 + metrics.actualBoundingBoxDescent; const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom; ctx.strokeStyle = ctx.fillStyle; ctx.beginPath(); ctx.lineWidth = opts.decorationWidth || 2; ctx.moveTo(left, yDecoration); ctx.lineTo(right, yDecoration); ctx.stroke(); } } function drawBackdrop(ctx, opts) { const oldColor = ctx.fillStyle; ctx.fillStyle = opts.color; ctx.fillRect(opts.left, opts.top, opts.width, opts.height); ctx.fillStyle = oldColor; } function renderText(ctx, text, x2, y2, font, opts = {}) { const lines = isArray(text) ? text : [ text ]; const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ""; let i2, line; ctx.save(); ctx.font = font.string; setRenderOpts(ctx, opts); for (i2 = 0; i2 < lines.length; ++i2) { line = lines[i2]; if (opts.backdrop) { drawBackdrop(ctx, opts.backdrop); } if (stroke) { if (opts.strokeColor) { ctx.strokeStyle = opts.strokeColor; } if (!isNullOrUndef(opts.strokeWidth)) { ctx.lineWidth = opts.strokeWidth; } ctx.strokeText(line, x2, y2, opts.maxWidth); } ctx.fillText(line, x2, y2, opts.maxWidth); decorateText(ctx, x2, y2, line, opts); y2 += Number(font.lineHeight); } ctx.restore(); } function addRoundedRectPath(ctx, rect) { const { x: x2, y: y2, w: w2, h: h6, radius } = rect; ctx.arc(x2 + radius.topLeft, y2 + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true); ctx.lineTo(x2, y2 + h6 - radius.bottomLeft); ctx.arc(x2 + radius.bottomLeft, y2 + h6 - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true); ctx.lineTo(x2 + w2 - radius.bottomRight, y2 + h6); ctx.arc(x2 + w2 - radius.bottomRight, y2 + h6 - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true); ctx.lineTo(x2 + w2, y2 + radius.topRight); ctx.arc(x2 + w2 - radius.topRight, y2 + radius.topRight, radius.topRight, 0, -HALF_PI, true); ctx.lineTo(x2 + radius.topLeft, y2); } var LINE_HEIGHT = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/; var FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/; function toLineHeight(value, size) { const matches = ("" + value).match(LINE_HEIGHT); if (!matches || matches[1] === "normal") { return size * 1.2; } value = +matches[2]; switch (matches[3]) { case "px": return value; case "%": value /= 100; break; } return size * value; } var numberOrZero = (v2) => +v2 || 0; function _readValueToProps(value, props) { const ret = {}; const objProps = isObject(props); const keys = objProps ? Object.keys(props) : props; const read = isObject(value) ? objProps ? (prop) => valueOrDefault(value[prop], value[props[prop]]) : (prop) => value[prop] : () => value; for (const prop of keys) { ret[prop] = numberOrZero(read(prop)); } return ret; } function toTRBL(value) { return _readValueToProps(value, { top: "y", right: "x", bottom: "y", left: "x" }); } function toTRBLCorners(value) { return _readValueToProps(value, [ "topLeft", "topRight", "bottomLeft", "bottomRight" ]); } function toPadding(value) { const obj = toTRBL(value); obj.width = obj.left + obj.right; obj.height = obj.top + obj.bottom; return obj; } function toFont(options, fallback) { options = options || {}; fallback = fallback || defaults2.font; let size = valueOrDefault(options.size, fallback.size); if (typeof size === "string") { size = parseInt(size, 10); } let style = valueOrDefault(options.style, fallback.style); if (style && !("" + style).match(FONT_STYLE)) { console.warn('Invalid font style specified: "' + style + '"'); style = void 0; } const font = { family: valueOrDefault(options.family, fallback.family), lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size), size, style, weight: valueOrDefault(options.weight, fallback.weight), string: "" }; font.string = toFontString(font); return font; } function resolve(inputs, context, index, info) { let cacheable = true; let i2, ilen, value; for (i2 = 0, ilen = inputs.length; i2 < ilen; ++i2) { value = inputs[i2]; if (value === void 0) { continue; } if (context !== void 0 && typeof value === "function") { value = value(context); cacheable = false; } if (index !== void 0 && isArray(value)) { value = value[index % value.length]; cacheable = false; } if (value !== void 0) { if (info && !cacheable) { info.cacheable = false; } return value; } } } function _addGrace(minmax, grace, beginAtZero) { const { min, max } = minmax; const change = toDimension(grace, (max - min) / 2); const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add; return { min: keepZero(min, -Math.abs(change)), max: keepZero(max, change) }; } function createContext(parentContext, context) { return Object.assign(Object.create(parentContext), context); } function _createResolver(scopes, prefixes = [ "" ], rootScopes, fallback, getTarget = () => scopes[0]) { const finalRootScopes = rootScopes || scopes; if (typeof fallback === "undefined") { fallback = _resolve("_fallback", scopes); } const cache = { [Symbol.toStringTag]: "Object", _cacheable: true, _scopes: scopes, _rootScopes: finalRootScopes, _fallback: fallback, _getTarget: getTarget, override: (scope) => _createResolver([ scope, ...scopes ], prefixes, finalRootScopes, fallback) }; return new Proxy(cache, { /** * A trap for the delete operator. */ deleteProperty(target, prop) { delete target[prop]; delete target._keys; delete scopes[0][prop]; return true; }, /** * A trap for getting property values. */ get(target, prop) { return _cached(target, prop, () => _resolveWithPrefixes(prop, prefixes, scopes, target)); }, /** * A trap for Object.getOwnPropertyDescriptor. * Also used by Object.hasOwnProperty. */ getOwnPropertyDescriptor(target, prop) { return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop); }, /** * A trap for Object.getPrototypeOf. */ getPrototypeOf() { return Reflect.getPrototypeOf(scopes[0]); }, /** * A trap for the in operator. */ has(target, prop) { return getKeysFromAllScopes(target).includes(prop); }, /** * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols. */ ownKeys(target) { return getKeysFromAllScopes(target); }, /** * A trap for setting property values. */ set(target, prop, value) { const storage = target._storage || (target._storage = getTarget()); target[prop] = storage[prop] = value; delete target._keys; return true; } }); } function _attachContext(proxy, context, subProxy, descriptorDefaults) { const cache = { _cacheable: false, _proxy: proxy, _context: context, _subProxy: subProxy, _stack: /* @__PURE__ */ new Set(), _descriptors: _descriptors(proxy, descriptorDefaults), setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults), override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults) }; return new Proxy(cache, { /** * A trap for the delete operator. */ deleteProperty(target, prop) { delete target[prop]; delete proxy[prop]; return true; }, /** * A trap for getting property values. */ get(target, prop, receiver) { return _cached(target, prop, () => _resolveWithContext(target, prop, receiver)); }, /** * A trap for Object.getOwnPropertyDescriptor. * Also used by Object.hasOwnProperty. */ getOwnPropertyDescriptor(target, prop) { return target._descriptors.allKeys ? Reflect.has(proxy, prop) ? { enumerable: true, configurable: true } : void 0 : Reflect.getOwnPropertyDescriptor(proxy, prop); }, /** * A trap for Object.getPrototypeOf. */ getPrototypeOf() { return Reflect.getPrototypeOf(proxy); }, /** * A trap for the in operator. */ has(target, prop) { return Reflect.has(proxy, prop); }, /** * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols. */ ownKeys() { return Reflect.ownKeys(proxy); }, /** * A trap for setting property values. */ set(target, prop, value) { proxy[prop] = value; delete target[prop]; return true; } }); } function _descriptors(proxy, defaults3 = { scriptable: true, indexable: true }) { const { _scriptable = defaults3.scriptable, _indexable = defaults3.indexable, _allKeys = defaults3.allKeys } = proxy; return { allKeys: _allKeys, scriptable: _scriptable, indexable: _indexable, isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable, isIndexable: isFunction(_indexable) ? _indexable : () => _indexable }; } var readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name; var needsSubResolver = (prop, value) => isObject(value) && prop !== "adapters" && (Object.getPrototypeOf(value) === null || value.constructor === Object); function _cached(target, prop, resolve2) { if (Object.prototype.hasOwnProperty.call(target, prop) || prop === "constructor") { return target[prop]; } const value = resolve2(); target[prop] = value; return value; } function _resolveWithContext(target, prop, receiver) { const { _proxy, _context, _subProxy, _descriptors: descriptors2 } = target; let value = _proxy[prop]; if (isFunction(value) && descriptors2.isScriptable(prop)) { value = _resolveScriptable(prop, value, target, receiver); } if (isArray(value) && value.length) { value = _resolveArray(prop, value, target, descriptors2.isIndexable); } if (needsSubResolver(prop, value)) { value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors2); } return value; } function _resolveScriptable(prop, getValue, target, receiver) { const { _proxy, _context, _subProxy, _stack } = target; if (_stack.has(prop)) { throw new Error("Recursion detected: " + Array.from(_stack).join("->") + "->" + prop); } _stack.add(prop); let value = getValue(_context, _subProxy || receiver); _stack.delete(prop); if (needsSubResolver(prop, value)) { value = createSubResolver(_proxy._scopes, _proxy, prop, value); } return value; } function _resolveArray(prop, value, target, isIndexable) { const { _proxy, _context, _subProxy, _descriptors: descriptors2 } = target; if (typeof _context.index !== "undefined" && isIndexable(prop)) { return value[_context.index % value.length]; } else if (isObject(value[0])) { const arr = value; const scopes = _proxy._scopes.filter((s2) => s2 !== arr); value = []; for (const item of arr) { const resolver = createSubResolver(scopes, _proxy, prop, item); value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors2)); } } return value; } function resolveFallback(fallback, prop, value) { return isFunction(fallback) ? fallback(prop, value) : fallback; } var getScope = (key, parent) => key === true ? parent : typeof key === "string" ? resolveObjectKey(parent, key) : void 0; function addScopes(set2, parentScopes, key, parentFallback, value) { for (const parent of parentScopes) { const scope = getScope(key, parent); if (scope) { set2.add(scope); const fallback = resolveFallback(scope._fallback, key, value); if (typeof fallback !== "undefined" && fallback !== key && fallback !== parentFallback) { return fallback; } } else if (scope === false && typeof parentFallback !== "undefined" && key !== parentFallback) { return null; } } return false; } function createSubResolver(parentScopes, resolver, prop, value) { const rootScopes = resolver._rootScopes; const fallback = resolveFallback(resolver._fallback, prop, value); const allScopes = [ ...parentScopes, ...rootScopes ]; const set2 = /* @__PURE__ */ new Set(); set2.add(value); let key = addScopesFromKey(set2, allScopes, prop, fallback || prop, value); if (key === null) { return false; } if (typeof fallback !== "undefined" && fallback !== prop) { key = addScopesFromKey(set2, allScopes, fallback, key, value); if (key === null) { return false; } } return _createResolver(Array.from(set2), [ "" ], rootScopes, fallback, () => subGetTarget(resolver, prop, value)); } function addScopesFromKey(set2, allScopes, key, fallback, item) { while (key) { key = addScopes(set2, allScopes, key, fallback, item); } return key; } function subGetTarget(resolver, prop, value) { const parent = resolver._getTarget(); if (!(prop in parent)) { parent[prop] = {}; } const target = parent[prop]; if (isArray(target) && isObject(value)) { return value; } return target || {}; } function _resolveWithPrefixes(prop, prefixes, scopes, proxy) { let value; for (const prefix of prefixes) { value = _resolve(readKey(prefix, prop), scopes); if (typeof value !== "undefined") { return needsSubResolver(prop, value) ? createSubResolver(scopes, proxy, prop, value) : value; } } } function _resolve(key, scopes) { for (const scope of scopes) { if (!scope) { continue; } const value = scope[key]; if (typeof value !== "undefined") { return value; } } } function getKeysFromAllScopes(target) { let keys = target._keys; if (!keys) { keys = target._keys = resolveKeysFromAllScopes(target._scopes); } return keys; } function resolveKeysFromAllScopes(scopes) { const set2 = /* @__PURE__ */ new Set(); for (const scope of scopes) { for (const key of Object.keys(scope).filter((k) => !k.startsWith("_"))) { set2.add(key); } } return Array.from(set2); } var EPSILON = Number.EPSILON || 1e-14; function _isDomSupported() { return typeof window !== "undefined" && typeof document !== "undefined"; } function _getParentNode(domNode) { let parent = domNode.parentNode; if (parent && parent.toString() === "[object ShadowRoot]") { parent = parent.host; } return parent; } function parseMaxStyle(styleValue, node, parentProperty) { let valueInPixels; if (typeof styleValue === "string") { valueInPixels = parseInt(styleValue, 10); if (styleValue.indexOf("%") !== -1) { valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; } } else { valueInPixels = styleValue; } return valueInPixels; } var getComputedStyle2 = (element) => element.ownerDocument.defaultView.getComputedStyle(element, null); function getStyle(el, property) { return getComputedStyle2(el).getPropertyValue(property); } var positions = [ "top", "right", "bottom", "left" ]; function getPositionedStyle(styles, style, suffix) { const result = {}; suffix = suffix ? "-" + suffix : ""; for (let i2 = 0; i2 < 4; i2++) { const pos = positions[i2]; result[pos] = parseFloat(styles[style + "-" + pos + suffix]) || 0; } result.width = result.left + result.right; result.height = result.top + result.bottom; return result; } var useOffsetPos = (x2, y2, target) => (x2 > 0 || y2 > 0) && (!target || !target.shadowRoot); function getCanvasPosition(e2, canvas) { const touches = e2.touches; const source = touches && touches.length ? touches[0] : e2; const { offsetX, offsetY } = source; let box = false; let x2, y2; if (useOffsetPos(offsetX, offsetY, e2.target)) { x2 = offsetX; y2 = offsetY; } else { const rect = canvas.getBoundingClientRect(); x2 = source.clientX - rect.left; y2 = source.clientY - rect.top; box = true; } return { x: x2, y: y2, box }; } function getRelativePosition(event, chart) { if ("native" in event) { return event; } const { canvas, currentDevicePixelRatio } = chart; const style = getComputedStyle2(canvas); const borderBox = style.boxSizing === "border-box"; const paddings = getPositionedStyle(style, "padding"); const borders = getPositionedStyle(style, "border", "width"); const { x: x2, y: y2, box } = getCanvasPosition(event, canvas); const xOffset = paddings.left + (box && borders.left); const yOffset = paddings.top + (box && borders.top); let { width, height } = chart; if (borderBox) { width -= paddings.width + borders.width; height -= paddings.height + borders.height; } return { x: Math.round((x2 - xOffset) / width * canvas.width / currentDevicePixelRatio), y: Math.round((y2 - yOffset) / height * canvas.height / currentDevicePixelRatio) }; } function getContainerSize(canvas, width, height) { let maxWidth, maxHeight; if (width === void 0 || height === void 0) { const container = canvas && _getParentNode(canvas); if (!container) { width = canvas.clientWidth; height = canvas.clientHeight; } else { const rect = container.getBoundingClientRect(); const containerStyle = getComputedStyle2(container); const containerBorder = getPositionedStyle(containerStyle, "border", "width"); const containerPadding = getPositionedStyle(containerStyle, "padding"); width = rect.width - containerPadding.width - containerBorder.width; height = rect.height - containerPadding.height - containerBorder.height; maxWidth = parseMaxStyle(containerStyle.maxWidth, container, "clientWidth"); maxHeight = parseMaxStyle(containerStyle.maxHeight, container, "clientHeight"); } } return { width, height, maxWidth: maxWidth || INFINITY, maxHeight: maxHeight || INFINITY }; } var round1 = (v2) => Math.round(v2 * 10) / 10; function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) { const style = getComputedStyle2(canvas); const margins = getPositionedStyle(style, "margin"); const maxWidth = parseMaxStyle(style.maxWidth, canvas, "clientWidth") || INFINITY; const maxHeight = parseMaxStyle(style.maxHeight, canvas, "clientHeight") || INFINITY; const containerSize = getContainerSize(canvas, bbWidth, bbHeight); let { width, height } = containerSize; if (style.boxSizing === "content-box") { const borders = getPositionedStyle(style, "border", "width"); const paddings = getPositionedStyle(style, "padding"); width -= paddings.width + borders.width; height -= paddings.height + borders.height; } width = Math.max(0, width - margins.width); height = Math.max(0, aspectRatio ? width / aspectRatio : height - margins.height); width = round1(Math.min(width, maxWidth, containerSize.maxWidth)); height = round1(Math.min(height, maxHeight, containerSize.maxHeight)); if (width && !height) { height = round1(width / 2); } const maintainHeight = bbWidth !== void 0 || bbHeight !== void 0; if (maintainHeight && aspectRatio && containerSize.height && height > containerSize.height) { height = containerSize.height; width = round1(Math.floor(height * aspectRatio)); } return { width, height }; } function retinaScale(chart, forceRatio, forceStyle) { const pixelRatio = forceRatio || 1; const deviceHeight = Math.floor(chart.height * pixelRatio); const deviceWidth = Math.floor(chart.width * pixelRatio); chart.height = Math.floor(chart.height); chart.width = Math.floor(chart.width); const canvas = chart.canvas; if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) { canvas.style.height = `${chart.height}px`; canvas.style.width = `${chart.width}px`; } if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) { chart.currentDevicePixelRatio = pixelRatio; canvas.height = deviceHeight; canvas.width = deviceWidth; chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); return true; } return false; } var supportsEventListenerOptions = function() { let passiveSupported = false; try { const options = { get passive() { passiveSupported = true; return false; } }; if (_isDomSupported()) { window.addEventListener("test", null, options); window.removeEventListener("test", null, options); } } catch (e2) { } return passiveSupported; }(); function readUsedSize(element, property) { const value = getStyle(element, property); const matches = value && value.match(/^(\d+)(\.\d+)?px$/); return matches ? +matches[1] : void 0; } var getRightToLeftAdapter = function(rectX, width) { return { x(x2) { return rectX + rectX + width - x2; }, setWidth(w2) { width = w2; }, textAlign(align) { if (align === "center") { return align; } return align === "right" ? "left" : "right"; }, xPlus(x2, value) { return x2 - value; }, leftForLtr(x2, itemWidth) { return x2 - itemWidth; } }; }; var getLeftToRightAdapter = function() { return { x(x2) { return x2; }, setWidth(w2) { }, textAlign(align) { return align; }, xPlus(x2, value) { return x2 + value; }, leftForLtr(x2, _itemWidth) { return x2; } }; }; function getRtlAdapter(rtl, rectX, width) { return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter(); } function overrideTextDirection(ctx, direction) { let style, original; if (direction === "ltr" || direction === "rtl") { style = ctx.canvas.style; original = [ style.getPropertyValue("direction"), style.getPropertyPriority("direction") ]; style.setProperty("direction", direction, "important"); ctx.prevTextDirection = original; } } function restoreTextDirection(ctx, original) { if (original !== void 0) { delete ctx.prevTextDirection; ctx.canvas.style.setProperty("direction", original[0], original[1]); } } // node_modules/.pnpm/chart.js@4.4.4/node_modules/chart.js/dist/chart.js var Animator = class { constructor() { this._request = null; this._charts = /* @__PURE__ */ new Map(); this._running = false; this._lastDate = void 0; } _notify(chart, anims, date, type) { const callbacks = anims.listeners[type]; const numSteps = anims.duration; callbacks.forEach((fn2) => fn2({ chart, initial: anims.initial, numSteps, currentStep: Math.min(date - anims.start, numSteps) })); } _refresh() { if (this._request) { return; } this._running = true; this._request = requestAnimFrame.call(window, () => { this._update(); this._request = null; if (this._running) { this._refresh(); } }); } _update(date = Date.now()) { let remaining = 0; this._charts.forEach((anims, chart) => { if (!anims.running || !anims.items.length) { return; } const items = anims.items; let i2 = items.length - 1; let draw = false; let item; for (; i2 >= 0; --i2) { item = items[i2]; if (item._active) { if (item._total > anims.duration) { anims.duration = item._total; } item.tick(date); draw = true; } else { items[i2] = items[items.length - 1]; items.pop(); } } if (draw) { chart.draw(); this._notify(chart, anims, date, "progress"); } if (!items.length) { anims.running = false; this._notify(chart, anims, date, "complete"); anims.initial = false; } remaining += items.length; }); this._lastDate = date; if (remaining === 0) { this._running = false; } } _getAnims(chart) { const charts = this._charts; let anims = charts.get(chart); if (!anims) { anims = { running: false, initial: true, items: [], listeners: { complete: [], progress: [] } }; charts.set(chart, anims); } return anims; } listen(chart, event, cb) { this._getAnims(chart).listeners[event].push(cb); } add(chart, items) { if (!items || !items.length) { return; } this._getAnims(chart).items.push(...items); } has(chart) { return this._getAnims(chart).items.length > 0; } start(chart) { const anims = this._charts.get(chart); if (!anims) { return; } anims.running = true; anims.start = Date.now(); anims.duration = anims.items.reduce((acc, cur) => Math.max(acc, cur._duration), 0); this._refresh(); } running(chart) { if (!this._running) { return false; } const anims = this._charts.get(chart); if (!anims || !anims.running || !anims.items.length) { return false; } return true; } stop(chart) { const anims = this._charts.get(chart); if (!anims || !anims.items.length) { return; } const items = anims.items; let i2 = items.length - 1; for (; i2 >= 0; --i2) { items[i2].cancel(); } anims.items = []; this._notify(chart, anims, Date.now(), "complete"); } remove(chart) { return this._charts.delete(chart); } }; var animator = /* @__PURE__ */ new Animator(); var transparent = "transparent"; var interpolators = { boolean(from2, to2, factor) { return factor > 0.5 ? to2 : from2; }, color(from2, to2, factor) { const c0 = color(from2 || transparent); const c1 = c0.valid && color(to2 || transparent); return c1 && c1.valid ? c1.mix(c0, factor).hexString() : to2; }, number(from2, to2, factor) { return from2 + (to2 - from2) * factor; } }; var Animation = class { constructor(cfg, target, prop, to2) { const currentValue = target[prop]; to2 = resolve([ cfg.to, to2, currentValue, cfg.from ]); const from2 = resolve([ cfg.from, currentValue, to2 ]); this._active = true; this._fn = cfg.fn || interpolators[cfg.type || typeof from2]; this._easing = effects[cfg.easing] || effects.linear; this._start = Math.floor(Date.now() + (cfg.delay || 0)); this._duration = this._total = Math.floor(cfg.duration); this._loop = !!cfg.loop; this._target = target; this._prop = prop; this._from = from2; this._to = to2; this._promises = void 0; } active() { return this._active; } update(cfg, to2, date) { if (this._active) { this._notify(false); const currentValue = this._target[this._prop]; const elapsed = date - this._start; const remain = this._duration - elapsed; this._start = date; this._duration = Math.floor(Math.max(remain, cfg.duration)); this._total += elapsed; this._loop = !!cfg.loop; this._to = resolve([ cfg.to, to2, currentValue, cfg.from ]); this._from = resolve([ cfg.from, currentValue, to2 ]); } } cancel() { if (this._active) { this.tick(Date.now()); this._active = false; this._notify(false); } } tick(date) { const elapsed = date - this._start; const duration = this._duration; const prop = this._prop; const from2 = this._from; const loop = this._loop; const to2 = this._to; let factor; this._active = from2 !== to2 && (loop || elapsed < duration); if (!this._active) { this._target[prop] = to2; this._notify(true); return; } if (elapsed < 0) { this._target[prop] = from2; return; } factor = elapsed / duration % 2; factor = loop && factor > 1 ? 2 - factor : factor; factor = this._easing(Math.min(1, Math.max(0, factor))); this._target[prop] = this._fn(from2, to2, factor); } wait() { const promises = this._promises || (this._promises = []); return new Promise((res, rej) => { promises.push({ res, rej }); }); } _notify(resolved) { const method = resolved ? "res" : "rej"; const promises = this._promises || []; for (let i2 = 0; i2 < promises.length; i2++) { promises[i2][method](); } } }; var Animations = class { constructor(chart, config) { this._chart = chart; this._properties = /* @__PURE__ */ new Map(); this.configure(config); } configure(config) { if (!isObject(config)) { return; } const animationOptions = Object.keys(defaults2.animation); const animatedProps = this._properties; Object.getOwnPropertyNames(config).forEach((key) => { const cfg = config[key]; if (!isObject(cfg)) { return; } const resolved = {}; for (const option of animationOptions) { resolved[option] = cfg[option]; } (isArray(cfg.properties) && cfg.properties || [ key ]).forEach((prop) => { if (prop === key || !animatedProps.has(prop)) { animatedProps.set(prop, resolved); } }); }); } _animateOptions(target, values) { const newOptions = values.options; const options = resolveTargetOptions(target, newOptions); if (!options) { return []; } const animations = this._createAnimations(options, newOptions); if (newOptions.$shared) { awaitAll(target.options.$animations, newOptions).then(() => { target.options = newOptions; }, () => { }); } return animations; } _createAnimations(target, values) { const animatedProps = this._properties; const animations = []; const running = target.$animations || (target.$animations = {}); const props = Object.keys(values); const date = Date.now(); let i2; for (i2 = props.length - 1; i2 >= 0; --i2) { const prop = props[i2]; if (prop.charAt(0) === "$") { continue; } if (prop === "options") { animations.push(...this._animateOptions(target, values)); continue; } const value = values[prop]; let animation = running[prop]; const cfg = animatedProps.get(prop); if (animation) { if (cfg && animation.active()) { animation.update(cfg, value, date); continue; } else { animation.cancel(); } } if (!cfg || !cfg.duration) { target[prop] = value; continue; } running[prop] = animation = new Animation(cfg, target, prop, value); animations.push(animation); } return animations; } update(target, values) { if (this._properties.size === 0) { Object.assign(target, values); return; } const animations = this._createAnimations(target, values); if (animations.length) { animator.add(this._chart, animations); return true; } } }; function awaitAll(animations, properties) { const running = []; const keys = Object.keys(properties); for (let i2 = 0; i2 < keys.length; i2++) { const anim = animations[keys[i2]]; if (anim && anim.active()) { running.push(anim.wait()); } } return Promise.all(running); } function resolveTargetOptions(target, newOptions) { if (!newOptions) { return; } let options = target.options; if (!options) { target.options = newOptions; return; } if (options.$shared) { target.options = options = Object.assign({}, options, { $shared: false, $animations: {} }); } return options; } function scaleClip(scale, allowedOverflow) { const opts = scale && scale.options || {}; const reverse = opts.reverse; const min = opts.min === void 0 ? allowedOverflow : 0; const max = opts.max === void 0 ? allowedOverflow : 0; return { start: reverse ? max : min, end: reverse ? min : max }; } function defaultClip(xScale, yScale, allowedOverflow) { if (allowedOverflow === false) { return false; } const x2 = scaleClip(xScale, allowedOverflow); const y2 = scaleClip(yScale, allowedOverflow); return { top: y2.end, right: x2.end, bottom: y2.start, left: x2.start }; } function toClip(value) { let t3, r2, b2, l2; if (isObject(value)) { t3 = value.top; r2 = value.right; b2 = value.bottom; l2 = value.left; } else { t3 = r2 = b2 = l2 = value; } return { top: t3, right: r2, bottom: b2, left: l2, disabled: value === false }; } function getSortedDatasetIndices(chart, filterVisible) { const keys = []; const metasets = chart._getSortedDatasetMetas(filterVisible); let i2, ilen; for (i2 = 0, ilen = metasets.length; i2 < ilen; ++i2) { keys.push(metasets[i2].index); } return keys; } function applyStack(stack, value, dsIndex, options = {}) { const keys = stack.keys; const singleMode = options.mode === "single"; let i2, ilen, datasetIndex, otherValue; if (value === null) { return; } for (i2 = 0, ilen = keys.length; i2 < ilen; ++i2) { datasetIndex = +keys[i2]; if (datasetIndex === dsIndex) { if (options.all) { continue; } break; } otherValue = stack.values[datasetIndex]; if (isNumberFinite(otherValue) && (singleMode || value === 0 || sign(value) === sign(otherValue))) { value += otherValue; } } return value; } function convertObjectDataToArray(data, meta) { const { iScale, vScale } = meta; const iAxisKey = iScale.axis === "x" ? "x" : "y"; const vAxisKey = vScale.axis === "x" ? "x" : "y"; const keys = Object.keys(data); const adata = new Array(keys.length); let i2, ilen, key; for (i2 = 0, ilen = keys.length; i2 < ilen; ++i2) { key = keys[i2]; adata[i2] = { [iAxisKey]: key, [vAxisKey]: data[key] }; } return adata; } function isStacked(scale, meta) { const stacked = scale && scale.options.stacked; return stacked || stacked === void 0 && meta.stack !== void 0; } function getStackKey(indexScale, valueScale, meta) { return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`; } function getUserBounds(scale) { const { min, max, minDefined, maxDefined } = scale.getUserBounds(); return { min: minDefined ? min : Number.NEGATIVE_INFINITY, max: maxDefined ? max : Number.POSITIVE_INFINITY }; } function getOrCreateStack(stacks, stackKey, indexValue) { const subStack = stacks[stackKey] || (stacks[stackKey] = {}); return subStack[indexValue] || (subStack[indexValue] = {}); } function getLastIndexInStack(stack, vScale, positive, type) { for (const meta of vScale.getMatchingVisibleMetas(type).reverse()) { const value = stack[meta.index]; if (positive && value > 0 || !positive && value < 0) { return meta.index; } } return null; } function updateStacks(controller, parsed) { const { chart, _cachedMeta: meta } = controller; const stacks = chart._stacks || (chart._stacks = {}); const { iScale, vScale, index: datasetIndex } = meta; const iAxis = iScale.axis; const vAxis = vScale.axis; const key = getStackKey(iScale, vScale, meta); const ilen = parsed.length; let stack; for (let i2 = 0; i2 < ilen; ++i2) { const item = parsed[i2]; const { [iAxis]: index, [vAxis]: value } = item; const itemStacks = item._stacks || (item._stacks = {}); stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index); stack[datasetIndex] = value; stack._top = getLastIndexInStack(stack, vScale, true, meta.type); stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type); const visualValues = stack._visualValues || (stack._visualValues = {}); visualValues[datasetIndex] = value; } } function getFirstScaleId(chart, axis) { const scales = chart.scales; return Object.keys(scales).filter((key) => scales[key].axis === axis).shift(); } function createDatasetContext(parent, index) { return createContext(parent, { active: false, dataset: void 0, datasetIndex: index, index, mode: "default", type: "dataset" }); } function createDataContext(parent, index, element) { return createContext(parent, { active: false, dataIndex: index, parsed: void 0, raw: void 0, element, index, mode: "default", type: "data" }); } function clearStacks(meta, items) { const datasetIndex = meta.controller.index; const axis = meta.vScale && meta.vScale.axis; if (!axis) { return; } items = items || meta._parsed; for (const parsed of items) { const stacks = parsed._stacks; if (!stacks || stacks[axis] === void 0 || stacks[axis][datasetIndex] === void 0) { return; } delete stacks[axis][datasetIndex]; if (stacks[axis]._visualValues !== void 0 && stacks[axis]._visualValues[datasetIndex] !== void 0) { delete stacks[axis]._visualValues[datasetIndex]; } } } var isDirectUpdateMode = (mode) => mode === "reset" || mode === "none"; var cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached); var createStack = (canStack, meta, chart) => canStack && !meta.hidden && meta._stacked && { keys: getSortedDatasetIndices(chart, true), values: null }; var DatasetController = class { constructor(chart, datasetIndex) { this.chart = chart; this._ctx = chart.ctx; this.index = datasetIndex; this._cachedDataOpts = {}; this._cachedMeta = this.getMeta(); this._type = this._cachedMeta.type; this.options = void 0; this._parsing = false; this._data = void 0; this._objectData = void 0; this._sharedOptions = void 0; this._drawStart = void 0; this._drawCount = void 0; this.enableOptionSharing = false; this.supportsDecimation = false; this.$context = void 0; this._syncList = []; this.datasetElementType = new.target.datasetElementType; this.dataElementType = new.target.dataElementType; this.initialize(); } initialize() { const meta = this._cachedMeta; this.configure(); this.linkScales(); meta._stacked = isStacked(meta.vScale, meta); this.addElements(); if (this.options.fill && !this.chart.isPluginEnabled("filler")) { console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options"); } } updateIndex(datasetIndex) { if (this.index !== datasetIndex) { clearStacks(this._cachedMeta); } this.index = datasetIndex; } linkScales() { const chart = this.chart; const meta = this._cachedMeta; const dataset = this.getDataset(); const chooseId = (axis, x2, y2, r2) => axis === "x" ? x2 : axis === "r" ? r2 : y2; const xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, "x")); const yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, "y")); const rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, "r")); const indexAxis = meta.indexAxis; const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid); const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid); meta.xScale = this.getScaleForId(xid); meta.yScale = this.getScaleForId(yid); meta.rScale = this.getScaleForId(rid); meta.iScale = this.getScaleForId(iid); meta.vScale = this.getScaleForId(vid); } getDataset() { return this.chart.data.datasets[this.index]; } getMeta() { return this.chart.getDatasetMeta(this.index); } getScaleForId(scaleID) { return this.chart.scales[scaleID]; } _getOtherScale(scale) { const meta = this._cachedMeta; return scale === meta.iScale ? meta.vScale : meta.iScale; } reset() { this._update("reset"); } _destroy() { const meta = this._cachedMeta; if (this._data) { unlistenArrayEvents(this._data, this); } if (meta._stacked) { clearStacks(meta); } } _dataCheck() { const dataset = this.getDataset(); const data = dataset.data || (dataset.data = []); const _data = this._data; if (isObject(data)) { const meta = this._cachedMeta; this._data = convertObjectDataToArray(data, meta); } else if (_data !== data) { if (_data) { unlistenArrayEvents(_data, this); const meta = this._cachedMeta; clearStacks(meta); meta._parsed = []; } if (data && Object.isExtensible(data)) { listenArrayEvents(data, this); } this._syncList = []; this._data = data; } } addElements() { const meta = this._cachedMeta; this._dataCheck(); if (this.datasetElementType) { meta.dataset = new this.datasetElementType(); } } buildOrUpdateElements(resetNewElements) { const meta = this._cachedMeta; const dataset = this.getDataset(); let stackChanged = false; this._dataCheck(); const oldStacked = meta._stacked; meta._stacked = isStacked(meta.vScale, meta); if (meta.stack !== dataset.stack) { stackChanged = true; clearStacks(meta); meta.stack = dataset.stack; } this._resyncElements(resetNewElements); if (stackChanged || oldStacked !== meta._stacked) { updateStacks(this, meta._parsed); } } configure() { const config = this.chart.config; const scopeKeys = config.datasetScopeKeys(this._type); const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true); this.options = config.createResolver(scopes, this.getContext()); this._parsing = this.options.parsing; this._cachedDataOpts = {}; } parse(start, count) { const { _cachedMeta: meta, _data: data } = this; const { iScale, _stacked } = meta; const iAxis = iScale.axis; let sorted = start === 0 && count === data.length ? true : meta._sorted; let prev = start > 0 && meta._parsed[start - 1]; let i2, cur, parsed; if (this._parsing === false) { meta._parsed = data; meta._sorted = true; parsed = data; } else { if (isArray(data[start])) { parsed = this.parseArrayData(meta, data, start, count); } else if (isObject(data[start])) { parsed = this.parseObjectData(meta, data, start, count); } else { parsed = this.parsePrimitiveData(meta, data, start, count); } const isNotInOrderComparedToPrev = () => cur[iAxis] === null || prev && cur[iAxis] < prev[iAxis]; for (i2 = 0; i2 < count; ++i2) { meta._parsed[i2 + start] = cur = parsed[i2]; if (sorted) { if (isNotInOrderComparedToPrev()) { sorted = false; } prev = cur; } } meta._sorted = sorted; } if (_stacked) { updateStacks(this, parsed); } } parsePrimitiveData(meta, data, start, count) { const { iScale, vScale } = meta; const iAxis = iScale.axis; const vAxis = vScale.axis; const labels = iScale.getLabels(); const singleScale = iScale === vScale; const parsed = new Array(count); let i2, ilen, index; for (i2 = 0, ilen = count; i2 < ilen; ++i2) { index = i2 + start; parsed[i2] = { [iAxis]: singleScale || iScale.parse(labels[index], index), [vAxis]: vScale.parse(data[index], index) }; } return parsed; } parseArrayData(meta, data, start, count) { const { xScale, yScale } = meta; const parsed = new Array(count); let i2, ilen, index, item; for (i2 = 0, ilen = count; i2 < ilen; ++i2) { index = i2 + start; item = data[index]; parsed[i2] = { x: xScale.parse(item[0], index), y: yScale.parse(item[1], index) }; } return parsed; } parseObjectData(meta, data, start, count) { const { xScale, yScale } = meta; const { xAxisKey = "x", yAxisKey = "y" } = this._parsing; const parsed = new Array(count); let i2, ilen, index, item; for (i2 = 0, ilen = count; i2 < ilen; ++i2) { index = i2 + start; item = data[index]; parsed[i2] = { x: xScale.parse(resolveObjectKey(item, xAxisKey), index), y: yScale.parse(resolveObjectKey(item, yAxisKey), index) }; } return parsed; } getParsed(index) { return this._cachedMeta._parsed[index]; } getDataElement(index) { return this._cachedMeta.data[index]; } applyStack(scale, parsed, mode) { const chart = this.chart; const meta = this._cachedMeta; const value = parsed[scale.axis]; const stack = { keys: getSortedDatasetIndices(chart, true), values: parsed._stacks[scale.axis]._visualValues }; return applyStack(stack, value, meta.index, { mode }); } updateRangeFromParsed(range, scale, parsed, stack) { const parsedValue = parsed[scale.axis]; let value = parsedValue === null ? NaN : parsedValue; const values = stack && parsed._stacks[scale.axis]; if (stack && values) { stack.values = values; value = applyStack(stack, parsedValue, this._cachedMeta.index); } range.min = Math.min(range.min, value); range.max = Math.max(range.max, value); } getMinMax(scale, canStack) { const meta = this._cachedMeta; const _parsed = meta._parsed; const sorted = meta._sorted && scale === meta.iScale; const ilen = _parsed.length; const otherScale = this._getOtherScale(scale); const stack = createStack(canStack, meta, this.chart); const range = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY }; const { min: otherMin, max: otherMax } = getUserBounds(otherScale); let i2, parsed; function _skip() { parsed = _parsed[i2]; const otherValue = parsed[otherScale.axis]; return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue; } for (i2 = 0; i2 < ilen; ++i2) { if (_skip()) { continue; } this.updateRangeFromParsed(range, scale, parsed, stack); if (sorted) { break; } } if (sorted) { for (i2 = ilen - 1; i2 >= 0; --i2) { if (_skip()) { continue; } this.updateRangeFromParsed(range, scale, parsed, stack); break; } } return range; } getAllParsedValues(scale) { const parsed = this._cachedMeta._parsed; const values = []; let i2, ilen, value; for (i2 = 0, ilen = parsed.length; i2 < ilen; ++i2) { value = parsed[i2][scale.axis]; if (isNumberFinite(value)) { values.push(value); } } return values; } getMaxOverflow() { return false; } getLabelAndValue(index) { const meta = this._cachedMeta; const iScale = meta.iScale; const vScale = meta.vScale; const parsed = this.getParsed(index); return { label: iScale ? "" + iScale.getLabelForValue(parsed[iScale.axis]) : "", value: vScale ? "" + vScale.getLabelForValue(parsed[vScale.axis]) : "" }; } _update(mode) { const meta = this._cachedMeta; this.update(mode || "default"); meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow()))); } update(mode) { } draw() { const ctx = this._ctx; const chart = this.chart; const meta = this._cachedMeta; const elements = meta.data || []; const area = chart.chartArea; const active = []; const start = this._drawStart || 0; const count = this._drawCount || elements.length - start; const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop; let i2; if (meta.dataset) { meta.dataset.draw(ctx, area, start, count); } for (i2 = start; i2 < start + count; ++i2) { const element = elements[i2]; if (element.hidden) { continue; } if (element.active && drawActiveElementsOnTop) { active.push(element); } else { element.draw(ctx, area); } } for (i2 = 0; i2 < active.length; ++i2) { active[i2].draw(ctx, area); } } getStyle(index, active) { const mode = active ? "active" : "default"; return index === void 0 && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(mode) : this.resolveDataElementOptions(index || 0, mode); } getContext(index, active, mode) { const dataset = this.getDataset(); let context; if (index >= 0 && index < this._cachedMeta.data.length) { const element = this._cachedMeta.data[index]; context = element.$context || (element.$context = createDataContext(this.getContext(), index, element)); context.parsed = this.getParsed(index); context.raw = dataset.data[index]; context.index = context.dataIndex = index; } else { context = this.$context || (this.$context = createDatasetContext(this.chart.getContext(), this.index)); context.dataset = dataset; context.index = context.datasetIndex = this.index; } context.active = !!active; context.mode = mode; return context; } resolveDatasetElementOptions(mode) { return this._resolveElementOptions(this.datasetElementType.id, mode); } resolveDataElementOptions(index, mode) { return this._resolveElementOptions(this.dataElementType.id, mode, index); } _resolveElementOptions(elementType, mode = "default", index) { const active = mode === "active"; const cache = this._cachedDataOpts; const cacheKey = elementType + "-" + mode; const cached = cache[cacheKey]; const sharing = this.enableOptionSharing && defined(index); if (cached) { return cloneIfNotShared(cached, sharing); } const config = this.chart.config; const scopeKeys = config.datasetElementScopeKeys(this._type, elementType); const prefixes = active ? [ `${elementType}Hover`, "hover", elementType, "" ] : [ elementType, "" ]; const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); const names2 = Object.keys(defaults2.elements[elementType]); const context = () => this.getContext(index, active, mode); const values = config.resolveNamedOptions(scopes, names2, context, prefixes); if (values.$shared) { values.$shared = sharing; cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing)); } return values; } _resolveAnimations(index, transition, active) { const chart = this.chart; const cache = this._cachedDataOpts; const cacheKey = `animation-${transition}`; const cached = cache[cacheKey]; if (cached) { return cached; } let options; if (chart.options.animation !== false) { const config = this.chart.config; const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition); const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); options = config.createResolver(scopes, this.getContext(index, active, transition)); } const animations = new Animations(chart, options && options.animations); if (options && options._cacheable) { cache[cacheKey] = Object.freeze(animations); } return animations; } getSharedOptions(options) { if (!options.$shared) { return; } return this._sharedOptions || (this._sharedOptions = Object.assign({}, options)); } includeOptions(mode, sharedOptions) { return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled; } _getSharedOptions(start, mode) { const firstOpts = this.resolveDataElementOptions(start, mode); const previouslySharedOptions = this._sharedOptions; const sharedOptions = this.getSharedOptions(firstOpts); const includeOptions = this.includeOptions(mode, sharedOptions) || sharedOptions !== previouslySharedOptions; this.updateSharedOptions(sharedOptions, mode, firstOpts); return { sharedOptions, includeOptions }; } updateElement(element, index, properties, mode) { if (isDirectUpdateMode(mode)) { Object.assign(element, properties); } else { this._resolveAnimations(index, mode).update(element, properties); } } updateSharedOptions(sharedOptions, mode, newOptions) { if (sharedOptions && !isDirectUpdateMode(mode)) { this._resolveAnimations(void 0, mode).update(sharedOptions, newOptions); } } _setStyle(element, index, mode, active) { element.active = active; const options = this.getStyle(index, active); this._resolveAnimations(index, mode, active).update(element, { options: !active && this.getSharedOptions(options) || options }); } removeHoverStyle(element, datasetIndex, index) { this._setStyle(element, index, "active", false); } setHoverStyle(element, datasetIndex, index) { this._setStyle(element, index, "active", true); } _removeDatasetHoverStyle() { const element = this._cachedMeta.dataset; if (element) { this._setStyle(element, void 0, "active", false); } } _setDatasetHoverStyle() { const element = this._cachedMeta.dataset; if (element) { this._setStyle(element, void 0, "active", true); } } _resyncElements(resetNewElements) { const data = this._data; const elements = this._cachedMeta.data; for (const [method, arg1, arg2] of this._syncList) { this[method](arg1, arg2); } this._syncList = []; const numMeta = elements.length; const numData = data.length; const count = Math.min(numData, numMeta); if (count) { this.parse(0, count); } if (numData > numMeta) { this._insertElements(numMeta, numData - numMeta, resetNewElements); } else if (numData < numMeta) { this._removeElements(numData, numMeta - numData); } } _insertElements(start, count, resetNewElements = true) { const meta = this._cachedMeta; const data = meta.data; const end = start + count; let i2; const move = (arr) => { arr.length += count; for (i2 = arr.length - 1; i2 >= end; i2--) { arr[i2] = arr[i2 - count]; } }; move(data); for (i2 = start; i2 < end; ++i2) { data[i2] = new this.dataElementType(); } if (this._parsing) { move(meta._parsed); } this.parse(start, count); if (resetNewElements) { this.updateElements(data, start, count, "reset"); } } updateElements(element, start, count, mode) { } _removeElements(start, count) { const meta = this._cachedMeta; if (this._parsing) { const removed = meta._parsed.splice(start, count); if (meta._stacked) { clearStacks(meta, removed); } } meta.data.splice(start, count); } _sync(args) { if (this._parsing) { this._syncList.push(args); } else { const [method, arg1, arg2] = args; this[method](arg1, arg2); } this.chart._dataChanges.push([ this.index, ...args ]); } _onDataPush() { const count = arguments.length; this._sync([ "_insertElements", this.getDataset().data.length - count, count ]); } _onDataPop() { this._sync([ "_removeElements", this._cachedMeta.data.length - 1, 1 ]); } _onDataShift() { this._sync([ "_removeElements", 0, 1 ]); } _onDataSplice(start, count) { if (count) { this._sync([ "_removeElements", start, count ]); } const newCount = arguments.length - 2; if (newCount) { this._sync([ "_insertElements", start, newCount ]); } } _onDataUnshift() { this._sync([ "_insertElements", 0, arguments.length ]); } }; __publicField(DatasetController, "defaults", {}); __publicField(DatasetController, "datasetElementType", null); __publicField(DatasetController, "dataElementType", null); function getAllScaleValues(scale, type) { if (!scale._cache.$bar) { const visibleMetas = scale.getMatchingVisibleMetas(type); let values = []; for (let i2 = 0, ilen = visibleMetas.length; i2 < ilen; i2++) { values = values.concat(visibleMetas[i2].controller.getAllParsedValues(scale)); } scale._cache.$bar = _arrayUnique(values.sort((a2, b2) => a2 - b2)); } return scale._cache.$bar; } function computeMinSampleSize(meta) { const scale = meta.iScale; const values = getAllScaleValues(scale, meta.type); let min = scale._length; let i2, ilen, curr, prev; const updateMinAndPrev = () => { if (curr === 32767 || curr === -32768) { return; } if (defined(prev)) { min = Math.min(min, Math.abs(curr - prev) || min); } prev = curr; }; for (i2 = 0, ilen = values.length; i2 < ilen; ++i2) { curr = scale.getPixelForValue(values[i2]); updateMinAndPrev(); } prev = void 0; for (i2 = 0, ilen = scale.ticks.length; i2 < ilen; ++i2) { curr = scale.getPixelForTick(i2); updateMinAndPrev(); } return min; } function computeFitCategoryTraits(index, ruler, options, stackCount) { const thickness = options.barThickness; let size, ratio; if (isNullOrUndef(thickness)) { size = ruler.min * options.categoryPercentage; ratio = options.barPercentage; } else { size = thickness * stackCount; ratio = 1; } return { chunk: size / stackCount, ratio, start: ruler.pixels[index] - size / 2 }; } function computeFlexCategoryTraits(index, ruler, options, stackCount) { const pixels = ruler.pixels; const curr = pixels[index]; let prev = index > 0 ? pixels[index - 1] : null; let next = index < pixels.length - 1 ? pixels[index + 1] : null; const percent = options.categoryPercentage; if (prev === null) { prev = curr - (next === null ? ruler.end - ruler.start : next - curr); } if (next === null) { next = curr + curr - prev; } const start = curr - (curr - Math.min(prev, next)) / 2 * percent; const size = Math.abs(next - prev) / 2 * percent; return { chunk: size / stackCount, ratio: options.barPercentage, start }; } function parseFloatBar(entry, item, vScale, i2) { const startValue = vScale.parse(entry[0], i2); const endValue = vScale.parse(entry[1], i2); const min = Math.min(startValue, endValue); const max = Math.max(startValue, endValue); let barStart = min; let barEnd = max; if (Math.abs(min) > Math.abs(max)) { barStart = max; barEnd = min; } item[vScale.axis] = barEnd; item._custom = { barStart, barEnd, start: startValue, end: endValue, min, max }; } function parseValue(entry, item, vScale, i2) { if (isArray(entry)) { parseFloatBar(entry, item, vScale, i2); } else { item[vScale.axis] = vScale.parse(entry, i2); } return item; } function parseArrayOrPrimitive(meta, data, start, count) { const iScale = meta.iScale; const vScale = meta.vScale; const labels = iScale.getLabels(); const singleScale = iScale === vScale; const parsed = []; let i2, ilen, item, entry; for (i2 = start, ilen = start + count; i2 < ilen; ++i2) { entry = data[i2]; item = {}; item[iScale.axis] = singleScale || iScale.parse(labels[i2], i2); parsed.push(parseValue(entry, item, vScale, i2)); } return parsed; } function isFloatBar(custom) { return custom && custom.barStart !== void 0 && custom.barEnd !== void 0; } function barSign(size, vScale, actualBase) { if (size !== 0) { return sign(size); } return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1); } function borderProps(properties) { let reverse, start, end, top, bottom; if (properties.horizontal) { reverse = properties.base > properties.x; start = "left"; end = "right"; } else { reverse = properties.base < properties.y; start = "bottom"; end = "top"; } if (reverse) { top = "end"; bottom = "start"; } else { top = "start"; bottom = "end"; } return { start, end, reverse, top, bottom }; } function setBorderSkipped(properties, options, stack, index) { let edge = options.borderSkipped; const res = {}; if (!edge) { properties.borderSkipped = res; return; } if (edge === true) { properties.borderSkipped = { top: true, right: true, bottom: true, left: true }; return; } const { start, end, reverse, top, bottom } = borderProps(properties); if (edge === "middle" && stack) { properties.enableBorderRadius = true; if ((stack._top || 0) === index) { edge = top; } else if ((stack._bottom || 0) === index) { edge = bottom; } else { res[parseEdge(bottom, start, end, reverse)] = true; edge = top; } } res[parseEdge(edge, start, end, reverse)] = true; properties.borderSkipped = res; } function parseEdge(edge, a2, b2, reverse) { if (reverse) { edge = swap(edge, a2, b2); edge = startEnd(edge, b2, a2); } else { edge = startEnd(edge, a2, b2); } return edge; } function swap(orig, v1, v2) { return orig === v1 ? v2 : orig === v2 ? v1 : orig; } function startEnd(v2, start, end) { return v2 === "start" ? start : v2 === "end" ? end : v2; } function setInflateAmount(properties, { inflateAmount }, ratio) { properties.inflateAmount = inflateAmount === "auto" ? ratio === 1 ? 0.33 : 0 : inflateAmount; } var BarController = class extends DatasetController { parsePrimitiveData(meta, data, start, count) { return parseArrayOrPrimitive(meta, data, start, count); } parseArrayData(meta, data, start, count) { return parseArrayOrPrimitive(meta, data, start, count); } parseObjectData(meta, data, start, count) { const { iScale, vScale } = meta; const { xAxisKey = "x", yAxisKey = "y" } = this._parsing; const iAxisKey = iScale.axis === "x" ? xAxisKey : yAxisKey; const vAxisKey = vScale.axis === "x" ? xAxisKey : yAxisKey; const parsed = []; let i2, ilen, item, obj; for (i2 = start, ilen = start + count; i2 < ilen; ++i2) { obj = data[i2]; item = {}; item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i2); parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i2)); } return parsed; } updateRangeFromParsed(range, scale, parsed, stack) { super.updateRangeFromParsed(range, scale, parsed, stack); const custom = parsed._custom; if (custom && scale === this._cachedMeta.vScale) { range.min = Math.min(range.min, custom.min); range.max = Math.max(range.max, custom.max); } } getMaxOverflow() { return 0; } getLabelAndValue(index) { const meta = this._cachedMeta; const { iScale, vScale } = meta; const parsed = this.getParsed(index); const custom = parsed._custom; const value = isFloatBar(custom) ? "[" + custom.start + ", " + custom.end + "]" : "" + vScale.getLabelForValue(parsed[vScale.axis]); return { label: "" + iScale.getLabelForValue(parsed[iScale.axis]), value }; } initialize() { this.enableOptionSharing = true; super.initialize(); const meta = this._cachedMeta; meta.stack = this.getDataset().stack; } update(mode) { const meta = this._cachedMeta; this.updateElements(meta.data, 0, meta.data.length, mode); } updateElements(bars, start, count, mode) { const reset2 = mode === "reset"; const { index, _cachedMeta: { vScale } } = this; const base = vScale.getBasePixel(); const horizontal = vScale.isHorizontal(); const ruler = this._getRuler(); const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); for (let i2 = start; i2 < start + count; i2++) { const parsed = this.getParsed(i2); const vpixels = reset2 || isNullOrUndef(parsed[vScale.axis]) ? { base, head: base } : this._calculateBarValuePixels(i2); const ipixels = this._calculateBarIndexPixels(i2, ruler); const stack = (parsed._stacks || {})[vScale.axis]; const properties = { horizontal, base: vpixels.base, enableBorderRadius: !stack || isFloatBar(parsed._custom) || index === stack._top || index === stack._bottom, x: horizontal ? vpixels.head : ipixels.center, y: horizontal ? ipixels.center : vpixels.head, height: horizontal ? ipixels.size : Math.abs(vpixels.size), width: horizontal ? Math.abs(vpixels.size) : ipixels.size }; if (includeOptions) { properties.options = sharedOptions || this.resolveDataElementOptions(i2, bars[i2].active ? "active" : mode); } const options = properties.options || bars[i2].options; setBorderSkipped(properties, options, stack, index); setInflateAmount(properties, options, ruler.ratio); this.updateElement(bars[i2], i2, properties, mode); } } _getStacks(last, dataIndex) { const { iScale } = this._cachedMeta; const metasets = iScale.getMatchingVisibleMetas(this._type).filter((meta) => meta.controller.options.grouped); const stacked = iScale.options.stacked; const stacks = []; const currentParsed = this._cachedMeta.controller.getParsed(dataIndex); const iScaleValue = currentParsed && currentParsed[iScale.axis]; const skipNull = (meta) => { const parsed = meta._parsed.find((item) => item[iScale.axis] === iScaleValue); const val = parsed && parsed[meta.vScale.axis]; if (isNullOrUndef(val) || isNaN(val)) { return true; } }; for (const meta of metasets) { if (dataIndex !== void 0 && skipNull(meta)) { continue; } if (stacked === false || stacks.indexOf(meta.stack) === -1 || stacked === void 0 && meta.stack === void 0) { stacks.push(meta.stack); } if (meta.index === last) { break; } } if (!stacks.length) { stacks.push(void 0); } return stacks; } _getStackCount(index) { return this._getStacks(void 0, index).length; } _getStackIndex(datasetIndex, name, dataIndex) { const stacks = this._getStacks(datasetIndex, dataIndex); const index = name !== void 0 ? stacks.indexOf(name) : -1; return index === -1 ? stacks.length - 1 : index; } _getRuler() { const opts = this.options; const meta = this._cachedMeta; const iScale = meta.iScale; const pixels = []; let i2, ilen; for (i2 = 0, ilen = meta.data.length; i2 < ilen; ++i2) { pixels.push(iScale.getPixelForValue(this.getParsed(i2)[iScale.axis], i2)); } const barThickness = opts.barThickness; const min = barThickness || computeMinSampleSize(meta); return { min, pixels, start: iScale._startPixel, end: iScale._endPixel, stackCount: this._getStackCount(), scale: iScale, grouped: opts.grouped, ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage }; } _calculateBarValuePixels(index) { const { _cachedMeta: { vScale, _stacked, index: datasetIndex }, options: { base: baseValue, minBarLength } } = this; const actualBase = baseValue || 0; const parsed = this.getParsed(index); const custom = parsed._custom; const floating = isFloatBar(custom); let value = parsed[vScale.axis]; let start = 0; let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value; let head, size; if (length !== value) { start = length - value; length = value; } if (floating) { value = custom.barStart; length = custom.barEnd - custom.barStart; if (value !== 0 && sign(value) !== sign(custom.barEnd)) { start = 0; } start += value; } const startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start; let base = vScale.getPixelForValue(startValue); if (this.chart.getDataVisibility(index)) { head = vScale.getPixelForValue(start + length); } else { head = base; } size = head - base; if (Math.abs(size) < minBarLength) { size = barSign(size, vScale, actualBase) * minBarLength; if (value === actualBase) { base -= size / 2; } const startPixel = vScale.getPixelForDecimal(0); const endPixel = vScale.getPixelForDecimal(1); const min = Math.min(startPixel, endPixel); const max = Math.max(startPixel, endPixel); base = Math.max(Math.min(base, max), min); head = base + size; if (_stacked && !floating) { parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base); } } if (base === vScale.getPixelForValue(actualBase)) { const halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2; base += halfGrid; size -= halfGrid; } return { size, base, head, center: head + size / 2 }; } _calculateBarIndexPixels(index, ruler) { const scale = ruler.scale; const options = this.options; const skipNull = options.skipNull; const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity); let center, size; if (ruler.grouped) { const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount; const range = options.barThickness === "flex" ? computeFlexCategoryTraits(index, ruler, options, stackCount) : computeFitCategoryTraits(index, ruler, options, stackCount); const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : void 0); center = range.start + range.chunk * stackIndex + range.chunk / 2; size = Math.min(maxBarThickness, range.chunk * range.ratio); } else { center = scale.getPixelForValue(this.getParsed(index)[scale.axis], index); size = Math.min(maxBarThickness, ruler.min * ruler.ratio); } return { base: center - size / 2, head: center + size / 2, center, size }; } draw() { const meta = this._cachedMeta; const vScale = meta.vScale; const rects = meta.data; const ilen = rects.length; let i2 = 0; for (; i2 < ilen; ++i2) { if (this.getParsed(i2)[vScale.axis] !== null && !rects[i2].hidden) { rects[i2].draw(this._ctx); } } } }; __publicField(BarController, "id", "bar"); __publicField(BarController, "defaults", { datasetElementType: false, dataElementType: "bar", categoryPercentage: 0.8, barPercentage: 0.9, grouped: true, animations: { numbers: { type: "number", properties: [ "x", "y", "base", "width", "height" ] } } }); __publicField(BarController, "overrides", { scales: { _index_: { type: "category", offset: true, grid: { offset: true } }, _value_: { type: "linear", beginAtZero: true } } }); function getRatioAndOffset(rotation, circumference, cutout) { let ratioX = 1; let ratioY = 1; let offsetX = 0; let offsetY = 0; if (circumference < TAU) { const startAngle = rotation; const endAngle = startAngle + circumference; const startX = Math.cos(startAngle); const startY = Math.sin(startAngle); const endX = Math.cos(endAngle); const endY = Math.sin(endAngle); const calcMax = (angle, a2, b2) => _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a2, a2 * cutout, b2, b2 * cutout); const calcMin = (angle, a2, b2) => _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a2, a2 * cutout, b2, b2 * cutout); const maxX = calcMax(0, startX, endX); const maxY = calcMax(HALF_PI, startY, endY); const minX = calcMin(PI, startX, endX); const minY = calcMin(PI + HALF_PI, startY, endY); ratioX = (maxX - minX) / 2; ratioY = (maxY - minY) / 2; offsetX = -(maxX + minX) / 2; offsetY = -(maxY + minY) / 2; } return { ratioX, ratioY, offsetX, offsetY }; } var DoughnutController = class extends DatasetController { constructor(chart, datasetIndex) { super(chart, datasetIndex); this.enableOptionSharing = true; this.innerRadius = void 0; this.outerRadius = void 0; this.offsetX = void 0; this.offsetY = void 0; } linkScales() { } parse(start, count) { const data = this.getDataset().data; const meta = this._cachedMeta; if (this._parsing === false) { meta._parsed = data; } else { let getter = (i3) => +data[i3]; if (isObject(data[start])) { const { key = "value" } = this._parsing; getter = (i3) => +resolveObjectKey(data[i3], key); } let i2, ilen; for (i2 = start, ilen = start + count; i2 < ilen; ++i2) { meta._parsed[i2] = getter(i2); } } } _getRotation() { return toRadians(this.options.rotation - 90); } _getCircumference() { return toRadians(this.options.circumference); } _getRotationExtents() { let min = TAU; let max = -TAU; for (let i2 = 0; i2 < this.chart.data.datasets.length; ++i2) { if (this.chart.isDatasetVisible(i2) && this.chart.getDatasetMeta(i2).type === this._type) { const controller = this.chart.getDatasetMeta(i2).controller; const rotation = controller._getRotation(); const circumference = controller._getCircumference(); min = Math.min(min, rotation); max = Math.max(max, rotation + circumference); } } return { rotation: min, circumference: max - min }; } update(mode) { const chart = this.chart; const { chartArea } = chart; const meta = this._cachedMeta; const arcs = meta.data; const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing; const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0); const cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1); const chartWeight = this._getRingWeight(this.index); const { circumference, rotation } = this._getRotationExtents(); const { ratioX, ratioY, offsetX, offsetY } = getRatioAndOffset(rotation, circumference, cutout); const maxWidth = (chartArea.width - spacing) / ratioX; const maxHeight = (chartArea.height - spacing) / ratioY; const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); const outerRadius = toDimension(this.options.radius, maxRadius); const innerRadius = Math.max(outerRadius * cutout, 0); const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal(); this.offsetX = offsetX * outerRadius; this.offsetY = offsetY * outerRadius; meta.total = this.calculateTotal(); this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index); this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0); this.updateElements(arcs, 0, arcs.length, mode); } _circumference(i2, reset2) { const opts = this.options; const meta = this._cachedMeta; const circumference = this._getCircumference(); if (reset2 && opts.animation.animateRotate || !this.chart.getDataVisibility(i2) || meta._parsed[i2] === null || meta.data[i2].hidden) { return 0; } return this.calculateCircumference(meta._parsed[i2] * circumference / TAU); } updateElements(arcs, start, count, mode) { const reset2 = mode === "reset"; const chart = this.chart; const chartArea = chart.chartArea; const opts = chart.options; const animationOpts = opts.animation; const centerX = (chartArea.left + chartArea.right) / 2; const centerY = (chartArea.top + chartArea.bottom) / 2; const animateScale = reset2 && animationOpts.animateScale; const innerRadius = animateScale ? 0 : this.innerRadius; const outerRadius = animateScale ? 0 : this.outerRadius; const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); let startAngle = this._getRotation(); let i2; for (i2 = 0; i2 < start; ++i2) { startAngle += this._circumference(i2, reset2); } for (i2 = start; i2 < start + count; ++i2) { const circumference = this._circumference(i2, reset2); const arc = arcs[i2]; const properties = { x: centerX + this.offsetX, y: centerY + this.offsetY, startAngle, endAngle: startAngle + circumference, circumference, outerRadius, innerRadius }; if (includeOptions) { properties.options = sharedOptions || this.resolveDataElementOptions(i2, arc.active ? "active" : mode); } startAngle += circumference; this.updateElement(arc, i2, properties, mode); } } calculateTotal() { const meta = this._cachedMeta; const metaData = meta.data; let total = 0; let i2; for (i2 = 0; i2 < metaData.length; i2++) { const value = meta._parsed[i2]; if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i2) && !metaData[i2].hidden) { total += Math.abs(value); } } return total; } calculateCircumference(value) { const total = this._cachedMeta.total; if (total > 0 && !isNaN(value)) { return TAU * (Math.abs(value) / total); } return 0; } getLabelAndValue(index) { const meta = this._cachedMeta; const chart = this.chart; const labels = chart.data.labels || []; const value = formatNumber(meta._parsed[index], chart.options.locale); return { label: labels[index] || "", value }; } getMaxBorderWidth(arcs) { let max = 0; const chart = this.chart; let i2, ilen, meta, controller, options; if (!arcs) { for (i2 = 0, ilen = chart.data.datasets.length; i2 < ilen; ++i2) { if (chart.isDatasetVisible(i2)) { meta = chart.getDatasetMeta(i2); arcs = meta.data; controller = meta.controller; break; } } } if (!arcs) { return 0; } for (i2 = 0, ilen = arcs.length; i2 < ilen; ++i2) { options = controller.resolveDataElementOptions(i2); if (options.borderAlign !== "inner") { max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0); } } return max; } getMaxOffset(arcs) { let max = 0; for (let i2 = 0, ilen = arcs.length; i2 < ilen; ++i2) { const options = this.resolveDataElementOptions(i2); max = Math.max(max, options.offset || 0, options.hoverOffset || 0); } return max; } _getRingWeightOffset(datasetIndex) { let ringWeightOffset = 0; for (let i2 = 0; i2 < datasetIndex; ++i2) { if (this.chart.isDatasetVisible(i2)) { ringWeightOffset += this._getRingWeight(i2); } } return ringWeightOffset; } _getRingWeight(datasetIndex) { return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0); } _getVisibleDatasetWeightTotal() { return this._getRingWeightOffset(this.chart.data.datasets.length) || 1; } }; __publicField(DoughnutController, "id", "doughnut"); __publicField(DoughnutController, "defaults", { datasetElementType: false, dataElementType: "arc", animation: { animateRotate: true, animateScale: false }, animations: { numbers: { type: "number", properties: [ "circumference", "endAngle", "innerRadius", "outerRadius", "startAngle", "x", "y", "offset", "borderWidth", "spacing" ] } }, cutout: "50%", rotation: 0, circumference: 360, radius: "100%", spacing: 0, indexAxis: "r" }); __publicField(DoughnutController, "descriptors", { _scriptable: (name) => name !== "spacing", _indexable: (name) => name !== "spacing" && !name.startsWith("borderDash") && !name.startsWith("hoverBorderDash") }); __publicField(DoughnutController, "overrides", { aspectRatio: 1, plugins: { legend: { labels: { generateLabels(chart) { const data = chart.data; if (data.labels.length && data.datasets.length) { const { labels: { pointStyle, color: color2 } } = chart.legend.options; return data.labels.map((label, i2) => { const meta = chart.getDatasetMeta(0); const style = meta.controller.getStyle(i2); return { text: label, fillStyle: style.backgroundColor, strokeStyle: style.borderColor, fontColor: color2, lineWidth: style.borderWidth, pointStyle, hidden: !chart.getDataVisibility(i2), index: i2 }; }); } return []; } }, onClick(e2, legendItem, legend) { legend.chart.toggleDataVisibility(legendItem.index); legend.chart.update(); } } } }); var PieController = class extends DoughnutController { }; __publicField(PieController, "id", "pie"); __publicField(PieController, "defaults", { cutout: 0, rotation: 0, circumference: 360, radius: "100%" }); function abstract() { throw new Error("This method is not implemented: Check that a complete date adapter is provided."); } var DateAdapterBase = class _DateAdapterBase { constructor(options) { __publicField(this, "options"); this.options = options || {}; } /** * Override default date adapter methods. * Accepts type parameter to define options type. * @example * Chart._adapters._date.override<{myAdapterOption: string}>({ * init() { * console.log(this.options.myAdapterOption); * } * }) */ static override(members) { Object.assign(_DateAdapterBase.prototype, members); } // eslint-disable-next-line @typescript-eslint/no-empty-function init() { } formats() { return abstract(); } parse() { return abstract(); } format() { return abstract(); } add() { return abstract(); } diff() { return abstract(); } startOf() { return abstract(); } endOf() { return abstract(); } }; var adapters = { _date: DateAdapterBase }; function binarySearch(metaset, axis, value, intersect) { const { controller, data, _sorted } = metaset; const iScale = controller._cachedMeta.iScale; if (iScale && axis === iScale.axis && axis !== "r" && _sorted && data.length) { const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey; if (!intersect) { return lookupMethod(data, axis, value); } else if (controller._sharedOptions) { const el = data[0]; const range = typeof el.getRange === "function" && el.getRange(axis); if (range) { const start = lookupMethod(data, axis, value - range); const end = lookupMethod(data, axis, value + range); return { lo: start.lo, hi: end.hi }; } } } return { lo: 0, hi: data.length - 1 }; } function evaluateInteractionItems(chart, axis, position, handler, intersect) { const metasets = chart.getSortedVisibleDatasetMetas(); const value = position[axis]; for (let i2 = 0, ilen = metasets.length; i2 < ilen; ++i2) { const { index, data } = metasets[i2]; const { lo, hi } = binarySearch(metasets[i2], axis, value, intersect); for (let j2 = lo; j2 <= hi; ++j2) { const element = data[j2]; if (!element.skip) { handler(element, index, j2); } } } } function getDistanceMetricForAxis(axis) { const useX = axis.indexOf("x") !== -1; const useY = axis.indexOf("y") !== -1; return function(pt1, pt2) { const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); }; } function getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) { const items = []; if (!includeInvisible && !chart.isPointInArea(position)) { return items; } const evaluationFunc = function(element, datasetIndex, index) { if (!includeInvisible && !_isPointInArea(element, chart.chartArea, 0)) { return; } if (element.inRange(position.x, position.y, useFinalPosition)) { items.push({ element, datasetIndex, index }); } }; evaluateInteractionItems(chart, axis, position, evaluationFunc, true); return items; } function getNearestRadialItems(chart, position, axis, useFinalPosition) { let items = []; function evaluationFunc(element, datasetIndex, index) { const { startAngle, endAngle } = element.getProps([ "startAngle", "endAngle" ], useFinalPosition); const { angle } = getAngleFromPoint(element, { x: position.x, y: position.y }); if (_angleBetween(angle, startAngle, endAngle)) { items.push({ element, datasetIndex, index }); } } evaluateInteractionItems(chart, axis, position, evaluationFunc); return items; } function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { let items = []; const distanceMetric = getDistanceMetricForAxis(axis); let minDistance = Number.POSITIVE_INFINITY; function evaluationFunc(element, datasetIndex, index) { const inRange2 = element.inRange(position.x, position.y, useFinalPosition); if (intersect && !inRange2) { return; } const center = element.getCenterPoint(useFinalPosition); const pointInArea = !!includeInvisible || chart.isPointInArea(center); if (!pointInArea && !inRange2) { return; } const distance = distanceMetric(position, center); if (distance < minDistance) { items = [ { element, datasetIndex, index } ]; minDistance = distance; } else if (distance === minDistance) { items.push({ element, datasetIndex, index }); } } evaluateInteractionItems(chart, axis, position, evaluationFunc); return items; } function getNearestItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { if (!includeInvisible && !chart.isPointInArea(position)) { return []; } return axis === "r" && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible); } function getAxisItems(chart, position, axis, intersect, useFinalPosition) { const items = []; const rangeMethod = axis === "x" ? "inXRange" : "inYRange"; let intersectsItem = false; evaluateInteractionItems(chart, axis, position, (element, datasetIndex, index) => { if (element[rangeMethod] && element[rangeMethod](position[axis], useFinalPosition)) { items.push({ element, datasetIndex, index }); intersectsItem = intersectsItem || element.inRange(position.x, position.y, useFinalPosition); } }); if (intersect && !intersectsItem) { return []; } return items; } var Interaction = { evaluateInteractionItems, modes: { index(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); const axis = options.axis || "x"; const includeInvisible = options.includeInvisible || false; const items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); const elements = []; if (!items.length) { return []; } chart.getSortedVisibleDatasetMetas().forEach((meta) => { const index = items[0].index; const element = meta.data[index]; if (element && !element.skip) { elements.push({ element, datasetIndex: meta.index, index }); } }); return elements; }, dataset(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); const axis = options.axis || "xy"; const includeInvisible = options.includeInvisible || false; let items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); if (items.length > 0) { const datasetIndex = items[0].datasetIndex; const data = chart.getDatasetMeta(datasetIndex).data; items = []; for (let i2 = 0; i2 < data.length; ++i2) { items.push({ element: data[i2], datasetIndex, index: i2 }); } } return items; }, point(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); const axis = options.axis || "xy"; const includeInvisible = options.includeInvisible || false; return getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible); }, nearest(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); const axis = options.axis || "xy"; const includeInvisible = options.includeInvisible || false; return getNearestItems(chart, position, axis, options.intersect, useFinalPosition, includeInvisible); }, x(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); return getAxisItems(chart, position, "x", options.intersect, useFinalPosition); }, y(chart, e2, options, useFinalPosition) { const position = getRelativePosition(e2, chart); return getAxisItems(chart, position, "y", options.intersect, useFinalPosition); } } }; var STATIC_POSITIONS = [ "left", "top", "right", "bottom" ]; function filterByPosition(array, position) { return array.filter((v2) => v2.pos === position); } function filterDynamicPositionByAxis(array, axis) { return array.filter((v2) => STATIC_POSITIONS.indexOf(v2.pos) === -1 && v2.box.axis === axis); } function sortByWeight(array, reverse) { return array.sort((a2, b2) => { const v0 = reverse ? b2 : a2; const v1 = reverse ? a2 : b2; return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight; }); } function wrapBoxes(boxes) { const layoutBoxes = []; let i2, ilen, box, pos, stack, stackWeight; for (i2 = 0, ilen = (boxes || []).length; i2 < ilen; ++i2) { box = boxes[i2]; ({ position: pos, options: { stack, stackWeight = 1 } } = box); layoutBoxes.push({ index: i2, box, pos, horizontal: box.isHorizontal(), weight: box.weight, stack: stack && pos + stack, stackWeight }); } return layoutBoxes; } function buildStacks(layouts2) { const stacks = {}; for (const wrap of layouts2) { const { stack, pos, stackWeight } = wrap; if (!stack || !STATIC_POSITIONS.includes(pos)) { continue; } const _stack = stacks[stack] || (stacks[stack] = { count: 0, placed: 0, weight: 0, size: 0 }); _stack.count++; _stack.weight += stackWeight; } return stacks; } function setLayoutDims(layouts2, params) { const stacks = buildStacks(layouts2); const { vBoxMaxWidth, hBoxMaxHeight } = params; let i2, ilen, layout; for (i2 = 0, ilen = layouts2.length; i2 < ilen; ++i2) { layout = layouts2[i2]; const { fullSize } = layout.box; const stack = stacks[layout.stack]; const factor = stack && layout.stackWeight / stack.weight; if (layout.horizontal) { layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth; layout.height = hBoxMaxHeight; } else { layout.width = vBoxMaxWidth; layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight; } } return stacks; } function buildLayoutBoxes(boxes) { const layoutBoxes = wrapBoxes(boxes); const fullSize = sortByWeight(layoutBoxes.filter((wrap) => wrap.box.fullSize), true); const left = sortByWeight(filterByPosition(layoutBoxes, "left"), true); const right = sortByWeight(filterByPosition(layoutBoxes, "right")); const top = sortByWeight(filterByPosition(layoutBoxes, "top"), true); const bottom = sortByWeight(filterByPosition(layoutBoxes, "bottom")); const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, "x"); const centerVertical = filterDynamicPositionByAxis(layoutBoxes, "y"); return { fullSize, leftAndTop: left.concat(top), rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal), chartArea: filterByPosition(layoutBoxes, "chartArea"), vertical: left.concat(right).concat(centerVertical), horizontal: top.concat(bottom).concat(centerHorizontal) }; } function getCombinedMax(maxPadding, chartArea, a2, b2) { return Math.max(maxPadding[a2], chartArea[a2]) + Math.max(maxPadding[b2], chartArea[b2]); } function updateMaxPadding(maxPadding, boxPadding) { maxPadding.top = Math.max(maxPadding.top, boxPadding.top); maxPadding.left = Math.max(maxPadding.left, boxPadding.left); maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); maxPadding.right = Math.max(maxPadding.right, boxPadding.right); } function updateDims(chartArea, params, layout, stacks) { const { pos, box } = layout; const maxPadding = chartArea.maxPadding; if (!isObject(pos)) { if (layout.size) { chartArea[pos] -= layout.size; } const stack = stacks[layout.stack] || { size: 0, count: 1 }; stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width); layout.size = stack.size / stack.count; chartArea[pos] += layout.size; } if (box.getPadding) { updateMaxPadding(maxPadding, box.getPadding()); } const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, "left", "right")); const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, "top", "bottom")); const widthChanged = newWidth !== chartArea.w; const heightChanged = newHeight !== chartArea.h; chartArea.w = newWidth; chartArea.h = newHeight; return layout.horizontal ? { same: widthChanged, other: heightChanged } : { same: heightChanged, other: widthChanged }; } function handleMaxPadding(chartArea) { const maxPadding = chartArea.maxPadding; function updatePos(pos) { const change = Math.max(maxPadding[pos] - chartArea[pos], 0); chartArea[pos] += change; return change; } chartArea.y += updatePos("top"); chartArea.x += updatePos("left"); updatePos("right"); updatePos("bottom"); } function getMargins(horizontal, chartArea) { const maxPadding = chartArea.maxPadding; function marginForPositions(positions2) { const margin = { left: 0, top: 0, right: 0, bottom: 0 }; positions2.forEach((pos) => { margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); }); return margin; } return horizontal ? marginForPositions([ "left", "right" ]) : marginForPositions([ "top", "bottom" ]); } function fitBoxes(boxes, chartArea, params, stacks) { const refitBoxes = []; let i2, ilen, layout, box, refit, changed; for (i2 = 0, ilen = boxes.length, refit = 0; i2 < ilen; ++i2) { layout = boxes[i2]; box = layout.box; box.update(layout.width || chartArea.w, layout.height || chartArea.h, getMargins(layout.horizontal, chartArea)); const { same, other } = updateDims(chartArea, params, layout, stacks); refit |= same && refitBoxes.length; changed = changed || other; if (!box.fullSize) { refitBoxes.push(layout); } } return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed; } function setBoxDims(box, left, top, width, height) { box.top = top; box.left = left; box.right = left + width; box.bottom = top + height; box.width = width; box.height = height; } function placeBoxes(boxes, chartArea, params, stacks) { const userPadding = params.padding; let { x: x2, y: y2 } = chartArea; for (const layout of boxes) { const box = layout.box; const stack = stacks[layout.stack] || { count: 1, placed: 0, weight: 1 }; const weight = layout.stackWeight / stack.weight || 1; if (layout.horizontal) { const width = chartArea.w * weight; const height = stack.size || box.height; if (defined(stack.start)) { y2 = stack.start; } if (box.fullSize) { setBoxDims(box, userPadding.left, y2, params.outerWidth - userPadding.right - userPadding.left, height); } else { setBoxDims(box, chartArea.left + stack.placed, y2, width, height); } stack.start = y2; stack.placed += width; y2 = box.bottom; } else { const height = chartArea.h * weight; const width = stack.size || box.width; if (defined(stack.start)) { x2 = stack.start; } if (box.fullSize) { setBoxDims(box, x2, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top); } else { setBoxDims(box, x2, chartArea.top + stack.placed, width, height); } stack.start = x2; stack.placed += height; x2 = box.right; } } chartArea.x = x2; chartArea.y = y2; } var layouts = { addBox(chart, item) { if (!chart.boxes) { chart.boxes = []; } item.fullSize = item.fullSize || false; item.position = item.position || "top"; item.weight = item.weight || 0; item._layers = item._layers || function() { return [ { z: 0, draw(chartArea) { item.draw(chartArea); } } ]; }; chart.boxes.push(item); }, removeBox(chart, layoutItem) { const index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; if (index !== -1) { chart.boxes.splice(index, 1); } }, configure(chart, item, options) { item.fullSize = options.fullSize; item.position = options.position; item.weight = options.weight; }, update(chart, width, height, minPadding) { if (!chart) { return; } const padding = toPadding(chart.options.layout.padding); const availableWidth = Math.max(width - padding.width, 0); const availableHeight = Math.max(height - padding.height, 0); const boxes = buildLayoutBoxes(chart.boxes); const verticalBoxes = boxes.vertical; const horizontalBoxes = boxes.horizontal; each(chart.boxes, (box) => { if (typeof box.beforeLayout === "function") { box.beforeLayout(); } }); const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap) => wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1; const params = Object.freeze({ outerWidth: width, outerHeight: height, padding, availableWidth, availableHeight, vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount, hBoxMaxHeight: availableHeight / 2 }); const maxPadding = Object.assign({}, padding); updateMaxPadding(maxPadding, toPadding(minPadding)); const chartArea = Object.assign({ maxPadding, w: availableWidth, h: availableHeight, x: padding.left, y: padding.top }, padding); const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); fitBoxes(boxes.fullSize, chartArea, params, stacks); fitBoxes(verticalBoxes, chartArea, params, stacks); if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) { fitBoxes(verticalBoxes, chartArea, params, stacks); } handleMaxPadding(chartArea); placeBoxes(boxes.leftAndTop, chartArea, params, stacks); chartArea.x += chartArea.w; chartArea.y += chartArea.h; placeBoxes(boxes.rightAndBottom, chartArea, params, stacks); chart.chartArea = { left: chartArea.left, top: chartArea.top, right: chartArea.left + chartArea.w, bottom: chartArea.top + chartArea.h, height: chartArea.h, width: chartArea.w }; each(boxes.chartArea, (layout) => { const box = layout.box; Object.assign(box, chart.chartArea); box.update(chartArea.w, chartArea.h, { left: 0, top: 0, right: 0, bottom: 0 }); }); } }; var BasePlatform = class { acquireContext(canvas, aspectRatio) { } releaseContext(context) { return false; } addEventListener(chart, type, listener) { } removeEventListener(chart, type, listener) { } getDevicePixelRatio() { return 1; } getMaximumSize(element, width, height, aspectRatio) { width = Math.max(0, width || element.width); height = height || element.height; return { width, height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height) }; } isAttached(canvas) { return true; } updateConfig(config) { } }; var BasicPlatform = class extends BasePlatform { acquireContext(item) { return item && item.getContext && item.getContext("2d") || null; } updateConfig(config) { config.options.animation = false; } }; var EXPANDO_KEY = "$chartjs"; var EVENT_TYPES = { touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup", pointerenter: "mouseenter", pointerdown: "mousedown", pointermove: "mousemove", pointerup: "mouseup", pointerleave: "mouseout", pointerout: "mouseout" }; var isNullOrEmpty = (value) => value === null || value === ""; function initCanvas(canvas, aspectRatio) { const style = canvas.style; const renderHeight = canvas.getAttribute("height"); const renderWidth = canvas.getAttribute("width"); canvas[EXPANDO_KEY] = { initial: { height: renderHeight, width: renderWidth, style: { display: style.display, height: style.height, width: style.width } } }; style.display = style.display || "block"; style.boxSizing = style.boxSizing || "border-box"; if (isNullOrEmpty(renderWidth)) { const displayWidth = readUsedSize(canvas, "width"); if (displayWidth !== void 0) { canvas.width = displayWidth; } } if (isNullOrEmpty(renderHeight)) { if (canvas.style.height === "") { canvas.height = canvas.width / (aspectRatio || 2); } else { const displayHeight = readUsedSize(canvas, "height"); if (displayHeight !== void 0) { canvas.height = displayHeight; } } } return canvas; } var eventListenerOptions = supportsEventListenerOptions ? { passive: true } : false; function addListener(node, type, listener) { if (node) { node.addEventListener(type, listener, eventListenerOptions); } } function removeListener(chart, type, listener) { if (chart && chart.canvas) { chart.canvas.removeEventListener(type, listener, eventListenerOptions); } } function fromNativeEvent(event, chart) { const type = EVENT_TYPES[event.type] || event.type; const { x: x2, y: y2 } = getRelativePosition(event, chart); return { type, chart, native: event, x: x2 !== void 0 ? x2 : null, y: y2 !== void 0 ? y2 : null }; } function nodeListContains(nodeList, canvas) { for (const node of nodeList) { if (node === canvas || node.contains(canvas)) { return true; } } } function createAttachObserver(chart, type, listener) { const canvas = chart.canvas; const observer = new MutationObserver((entries) => { let trigger = false; for (const entry of entries) { trigger = trigger || nodeListContains(entry.addedNodes, canvas); trigger = trigger && !nodeListContains(entry.removedNodes, canvas); } if (trigger) { listener(); } }); observer.observe(document, { childList: true, subtree: true }); return observer; } function createDetachObserver(chart, type, listener) { const canvas = chart.canvas; const observer = new MutationObserver((entries) => { let trigger = false; for (const entry of entries) { trigger = trigger || nodeListContains(entry.removedNodes, canvas); trigger = trigger && !nodeListContains(entry.addedNodes, canvas); } if (trigger) { listener(); } }); observer.observe(document, { childList: true, subtree: true }); return observer; } var drpListeningCharts = /* @__PURE__ */ new Map(); var oldDevicePixelRatio = 0; function onWindowResize() { const dpr = window.devicePixelRatio; if (dpr === oldDevicePixelRatio) { return; } oldDevicePixelRatio = dpr; drpListeningCharts.forEach((resize, chart) => { if (chart.currentDevicePixelRatio !== dpr) { resize(); } }); } function listenDevicePixelRatioChanges(chart, resize) { if (!drpListeningCharts.size) { window.addEventListener("resize", onWindowResize); } drpListeningCharts.set(chart, resize); } function unlistenDevicePixelRatioChanges(chart) { drpListeningCharts.delete(chart); if (!drpListeningCharts.size) { window.removeEventListener("resize", onWindowResize); } } function createResizeObserver(chart, type, listener) { const canvas = chart.canvas; const container = canvas && _getParentNode(canvas); if (!container) { return; } const resize = throttled((width, height) => { const w2 = container.clientWidth; listener(width, height); if (w2 < container.clientWidth) { listener(); } }, window); const observer = new ResizeObserver((entries) => { const entry = entries[0]; const width = entry.contentRect.width; const height = entry.contentRect.height; if (width === 0 && height === 0) { return; } resize(width, height); }); observer.observe(container); listenDevicePixelRatioChanges(chart, resize); return observer; } function releaseObserver(chart, type, observer) { if (observer) { observer.disconnect(); } if (type === "resize") { unlistenDevicePixelRatioChanges(chart); } } function createProxyAndListen(chart, type, listener) { const canvas = chart.canvas; const proxy = throttled((event) => { if (chart.ctx !== null) { listener(fromNativeEvent(event, chart)); } }, chart); addListener(canvas, type, proxy); return proxy; } var DomPlatform = class extends BasePlatform { acquireContext(canvas, aspectRatio) { const context = canvas && canvas.getContext && canvas.getContext("2d"); if (context && context.canvas === canvas) { initCanvas(canvas, aspectRatio); return context; } return null; } releaseContext(context) { const canvas = context.canvas; if (!canvas[EXPANDO_KEY]) { return false; } const initial = canvas[EXPANDO_KEY].initial; [ "height", "width" ].forEach((prop) => { const value = initial[prop]; if (isNullOrUndef(value)) { canvas.removeAttribute(prop); } else { canvas.setAttribute(prop, value); } }); const style = initial.style || {}; Object.keys(style).forEach((key) => { canvas.style[key] = style[key]; }); canvas.width = canvas.width; delete canvas[EXPANDO_KEY]; return true; } addEventListener(chart, type, listener) { this.removeEventListener(chart, type); const proxies = chart.$proxies || (chart.$proxies = {}); const handlers = { attach: createAttachObserver, detach: createDetachObserver, resize: createResizeObserver }; const handler = handlers[type] || createProxyAndListen; proxies[type] = handler(chart, type, listener); } removeEventListener(chart, type) { const proxies = chart.$proxies || (chart.$proxies = {}); const proxy = proxies[type]; if (!proxy) { return; } const handlers = { attach: releaseObserver, detach: releaseObserver, resize: releaseObserver }; const handler = handlers[type] || removeListener; handler(chart, type, proxy); proxies[type] = void 0; } getDevicePixelRatio() { return window.devicePixelRatio; } getMaximumSize(canvas, width, height, aspectRatio) { return getMaximumSize(canvas, width, height, aspectRatio); } isAttached(canvas) { const container = canvas && _getParentNode(canvas); return !!(container && container.isConnected); } }; function _detectPlatform(canvas) { if (!_isDomSupported() || typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) { return BasicPlatform; } return DomPlatform; } var Element = class { constructor() { __publicField(this, "x"); __publicField(this, "y"); __publicField(this, "active", false); __publicField(this, "options"); __publicField(this, "$animations"); } tooltipPosition(useFinalPosition) { const { x: x2, y: y2 } = this.getProps([ "x", "y" ], useFinalPosition); return { x: x2, y: y2 }; } hasValue() { return isNumber(this.x) && isNumber(this.y); } getProps(props, final) { const anims = this.$animations; if (!final || !anims) { return this; } const ret = {}; props.forEach((prop) => { ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop]; }); return ret; } }; __publicField(Element, "defaults", {}); __publicField(Element, "defaultRoutes"); function autoSkip(scale, ticks) { const tickOpts = scale.options.ticks; const determinedMaxTicks = determineMaxTicks(scale); const ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks); const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : []; const numMajorIndices = majorIndices.length; const first = majorIndices[0]; const last = majorIndices[numMajorIndices - 1]; const newTicks = []; if (numMajorIndices > ticksLimit) { skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit); return newTicks; } const spacing = calculateSpacing(majorIndices, ticks, ticksLimit); if (numMajorIndices > 0) { let i2, ilen; const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null; skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first); for (i2 = 0, ilen = numMajorIndices - 1; i2 < ilen; i2++) { skip(ticks, newTicks, spacing, majorIndices[i2], majorIndices[i2 + 1]); } skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing); return newTicks; } skip(ticks, newTicks, spacing); return newTicks; } function determineMaxTicks(scale) { const offset = scale.options.offset; const tickLength = scale._tickSize(); const maxScale = scale._length / tickLength + (offset ? 0 : 1); const maxChart = scale._maxLength / tickLength; return Math.floor(Math.min(maxScale, maxChart)); } function calculateSpacing(majorIndices, ticks, ticksLimit) { const evenMajorSpacing = getEvenSpacing(majorIndices); const spacing = ticks.length / ticksLimit; if (!evenMajorSpacing) { return Math.max(spacing, 1); } const factors = _factorize(evenMajorSpacing); for (let i2 = 0, ilen = factors.length - 1; i2 < ilen; i2++) { const factor = factors[i2]; if (factor > spacing) { return factor; } } return Math.max(spacing, 1); } function getMajorIndices(ticks) { const result = []; let i2, ilen; for (i2 = 0, ilen = ticks.length; i2 < ilen; i2++) { if (ticks[i2].major) { result.push(i2); } } return result; } function skipMajors(ticks, newTicks, majorIndices, spacing) { let count = 0; let next = majorIndices[0]; let i2; spacing = Math.ceil(spacing); for (i2 = 0; i2 < ticks.length; i2++) { if (i2 === next) { newTicks.push(ticks[i2]); count++; next = majorIndices[count * spacing]; } } } function skip(ticks, newTicks, spacing, majorStart, majorEnd) { const start = valueOrDefault(majorStart, 0); const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length); let count = 0; let length, i2, next; spacing = Math.ceil(spacing); if (majorEnd) { length = majorEnd - majorStart; spacing = length / Math.floor(length / spacing); } next = start; while (next < 0) { count++; next = Math.round(start + count * spacing); } for (i2 = Math.max(start, 0); i2 < end; i2++) { if (i2 === next) { newTicks.push(ticks[i2]); count++; next = Math.round(start + count * spacing); } } } function getEvenSpacing(arr) { const len = arr.length; let i2, diff; if (len < 2) { return false; } for (diff = arr[0], i2 = 1; i2 < len; ++i2) { if (arr[i2] - arr[i2 - 1] !== diff) { return false; } } return diff; } var reverseAlign = (align) => align === "left" ? "right" : align === "right" ? "left" : align; var offsetFromEdge = (scale, edge, offset) => edge === "top" || edge === "left" ? scale[edge] + offset : scale[edge] - offset; var getTicksLimit = (ticksLength, maxTicksLimit) => Math.min(maxTicksLimit || ticksLength, ticksLength); function sample(arr, numItems) { const result = []; const increment = arr.length / numItems; const len = arr.length; let i2 = 0; for (; i2 < len; i2 += increment) { result.push(arr[Math.floor(i2)]); } return result; } function getPixelForGridLine(scale, index, offsetGridLines) { const length = scale.ticks.length; const validIndex2 = Math.min(index, length - 1); const start = scale._startPixel; const end = scale._endPixel; const epsilon = 1e-6; let lineValue = scale.getPixelForTick(validIndex2); let offset; if (offsetGridLines) { if (length === 1) { offset = Math.max(lineValue - start, end - lineValue); } else if (index === 0) { offset = (scale.getPixelForTick(1) - lineValue) / 2; } else { offset = (lineValue - scale.getPixelForTick(validIndex2 - 1)) / 2; } lineValue += validIndex2 < index ? offset : -offset; if (lineValue < start - epsilon || lineValue > end + epsilon) { return; } } return lineValue; } function garbageCollect(caches, length) { each(caches, (cache) => { const gc = cache.gc; const gcLen = gc.length / 2; let i2; if (gcLen > length) { for (i2 = 0; i2 < gcLen; ++i2) { delete cache.data[gc[i2]]; } gc.splice(0, gcLen); } }); } function getTickMarkLength(options) { return options.drawTicks ? options.tickLength : 0; } function getTitleHeight(options, fallback) { if (!options.display) { return 0; } const font = toFont(options.font, fallback); const padding = toPadding(options.padding); const lines = isArray(options.text) ? options.text.length : 1; return lines * font.lineHeight + padding.height; } function createScaleContext(parent, scale) { return createContext(parent, { scale, type: "scale" }); } function createTickContext(parent, index, tick) { return createContext(parent, { tick, index, type: "tick" }); } function titleAlign(align, position, reverse) { let ret = _toLeftRightCenter(align); if (reverse && position !== "right" || !reverse && position === "right") { ret = reverseAlign(ret); } return ret; } function titleArgs(scale, offset, position, align) { const { top, left, bottom, right, chart } = scale; const { chartArea, scales } = chart; let rotation = 0; let maxWidth, titleX, titleY; const height = bottom - top; const width = right - left; if (scale.isHorizontal()) { titleX = _alignStartEnd(align, left, right); if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; titleY = scales[positionAxisID].getPixelForValue(value) + height - offset; } else if (position === "center") { titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset; } else { titleY = offsetFromEdge(scale, position, offset); } maxWidth = right - left; } else { if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; titleX = scales[positionAxisID].getPixelForValue(value) - width + offset; } else if (position === "center") { titleX = (chartArea.left + chartArea.right) / 2 - width + offset; } else { titleX = offsetFromEdge(scale, position, offset); } titleY = _alignStartEnd(align, bottom, top); rotation = position === "left" ? -HALF_PI : HALF_PI; } return { titleX, titleY, maxWidth, rotation }; } var Scale = class _Scale extends Element { constructor(cfg) { super(); this.id = cfg.id; this.type = cfg.type; this.options = void 0; this.ctx = cfg.ctx; this.chart = cfg.chart; this.top = void 0; this.bottom = void 0; this.left = void 0; this.right = void 0; this.width = void 0; this.height = void 0; this._margins = { left: 0, right: 0, top: 0, bottom: 0 }; this.maxWidth = void 0; this.maxHeight = void 0; this.paddingTop = void 0; this.paddingBottom = void 0; this.paddingLeft = void 0; this.paddingRight = void 0; this.axis = void 0; this.labelRotation = void 0; this.min = void 0; this.max = void 0; this._range = void 0; this.ticks = []; this._gridLineItems = null; this._labelItems = null; this._labelSizes = null; this._length = 0; this._maxLength = 0; this._longestTextCache = {}; this._startPixel = void 0; this._endPixel = void 0; this._reversePixels = false; this._userMax = void 0; this._userMin = void 0; this._suggestedMax = void 0; this._suggestedMin = void 0; this._ticksLength = 0; this._borderValue = 0; this._cache = {}; this._dataLimitsCached = false; this.$context = void 0; } init(options) { this.options = options.setContext(this.getContext()); this.axis = options.axis; this._userMin = this.parse(options.min); this._userMax = this.parse(options.max); this._suggestedMin = this.parse(options.suggestedMin); this._suggestedMax = this.parse(options.suggestedMax); } parse(raw, index) { return raw; } getUserBounds() { let { _userMin, _userMax, _suggestedMin, _suggestedMax } = this; _userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY); _userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY); _suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY); _suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY); return { min: finiteOrDefault(_userMin, _suggestedMin), max: finiteOrDefault(_userMax, _suggestedMax), minDefined: isNumberFinite(_userMin), maxDefined: isNumberFinite(_userMax) }; } getMinMax(canStack) { let { min, max, minDefined, maxDefined } = this.getUserBounds(); let range; if (minDefined && maxDefined) { return { min, max }; } const metas = this.getMatchingVisibleMetas(); for (let i2 = 0, ilen = metas.length; i2 < ilen; ++i2) { range = metas[i2].controller.getMinMax(this, canStack); if (!minDefined) { min = Math.min(min, range.min); } if (!maxDefined) { max = Math.max(max, range.max); } } min = maxDefined && min > max ? max : min; max = minDefined && min > max ? min : max; return { min: finiteOrDefault(min, finiteOrDefault(max, min)), max: finiteOrDefault(max, finiteOrDefault(min, max)) }; } getPadding() { return { left: this.paddingLeft || 0, top: this.paddingTop || 0, right: this.paddingRight || 0, bottom: this.paddingBottom || 0 }; } getTicks() { return this.ticks; } getLabels() { const data = this.chart.data; return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || []; } getLabelItems(chartArea = this.chart.chartArea) { const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea)); return items; } beforeLayout() { this._cache = {}; this._dataLimitsCached = false; } beforeUpdate() { callback(this.options.beforeUpdate, [ this ]); } update(maxWidth, maxHeight, margins) { const { beginAtZero, grace, ticks: tickOpts } = this.options; const sampleSize = tickOpts.sampleSize; this.beforeUpdate(); this.maxWidth = maxWidth; this.maxHeight = maxHeight; this._margins = margins = Object.assign({ left: 0, right: 0, top: 0, bottom: 0 }, margins); this.ticks = null; this._labelSizes = null; this._gridLineItems = null; this._labelItems = null; this.beforeSetDimensions(); this.setDimensions(); this.afterSetDimensions(); this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom; if (!this._dataLimitsCached) { this.beforeDataLimits(); this.determineDataLimits(); this.afterDataLimits(); this._range = _addGrace(this, grace, beginAtZero); this._dataLimitsCached = true; } this.beforeBuildTicks(); this.ticks = this.buildTicks() || []; this.afterBuildTicks(); const samplingEnabled = sampleSize < this.ticks.length; this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks); this.configure(); this.beforeCalculateLabelRotation(); this.calculateLabelRotation(); this.afterCalculateLabelRotation(); if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === "auto")) { this.ticks = autoSkip(this, this.ticks); this._labelSizes = null; this.afterAutoSkip(); } if (samplingEnabled) { this._convertTicksToLabels(this.ticks); } this.beforeFit(); this.fit(); this.afterFit(); this.afterUpdate(); } configure() { let reversePixels = this.options.reverse; let startPixel, endPixel; if (this.isHorizontal()) { startPixel = this.left; endPixel = this.right; } else { startPixel = this.top; endPixel = this.bottom; reversePixels = !reversePixels; } this._startPixel = startPixel; this._endPixel = endPixel; this._reversePixels = reversePixels; this._length = endPixel - startPixel; this._alignToPixels = this.options.alignToPixels; } afterUpdate() { callback(this.options.afterUpdate, [ this ]); } beforeSetDimensions() { callback(this.options.beforeSetDimensions, [ this ]); } setDimensions() { if (this.isHorizontal()) { this.width = this.maxWidth; this.left = 0; this.right = this.width; } else { this.height = this.maxHeight; this.top = 0; this.bottom = this.height; } this.paddingLeft = 0; this.paddingTop = 0; this.paddingRight = 0; this.paddingBottom = 0; } afterSetDimensions() { callback(this.options.afterSetDimensions, [ this ]); } _callHooks(name) { this.chart.notifyPlugins(name, this.getContext()); callback(this.options[name], [ this ]); } beforeDataLimits() { this._callHooks("beforeDataLimits"); } determineDataLimits() { } afterDataLimits() { this._callHooks("afterDataLimits"); } beforeBuildTicks() { this._callHooks("beforeBuildTicks"); } buildTicks() { return []; } afterBuildTicks() { this._callHooks("afterBuildTicks"); } beforeTickToLabelConversion() { callback(this.options.beforeTickToLabelConversion, [ this ]); } generateTickLabels(ticks) { const tickOpts = this.options.ticks; let i2, ilen, tick; for (i2 = 0, ilen = ticks.length; i2 < ilen; i2++) { tick = ticks[i2]; tick.label = callback(tickOpts.callback, [ tick.value, i2, ticks ], this); } } afterTickToLabelConversion() { callback(this.options.afterTickToLabelConversion, [ this ]); } beforeCalculateLabelRotation() { callback(this.options.beforeCalculateLabelRotation, [ this ]); } calculateLabelRotation() { const options = this.options; const tickOpts = options.ticks; const numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit); const minRotation = tickOpts.minRotation || 0; const maxRotation = tickOpts.maxRotation; let labelRotation = minRotation; let tickWidth, maxHeight, maxLabelDiagonal; if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) { this.labelRotation = minRotation; return; } const labelSizes = this._getLabelSizes(); const maxLabelWidth = labelSizes.widest.width; const maxLabelHeight = labelSizes.highest.height; const maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth); tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1); if (maxLabelWidth + 6 > tickWidth) { tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1)); maxHeight = this.maxHeight - getTickMarkLength(options.grid) - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font); maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight); labelRotation = toDegrees(Math.min(Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1)))); labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation)); } this.labelRotation = labelRotation; } afterCalculateLabelRotation() { callback(this.options.afterCalculateLabelRotation, [ this ]); } afterAutoSkip() { } beforeFit() { callback(this.options.beforeFit, [ this ]); } fit() { const minSize = { width: 0, height: 0 }; const { chart, options: { ticks: tickOpts, title: titleOpts, grid: gridOpts } } = this; const display = this._isVisible(); const isHorizontal = this.isHorizontal(); if (display) { const titleHeight = getTitleHeight(titleOpts, chart.options.font); if (isHorizontal) { minSize.width = this.maxWidth; minSize.height = getTickMarkLength(gridOpts) + titleHeight; } else { minSize.height = this.maxHeight; minSize.width = getTickMarkLength(gridOpts) + titleHeight; } if (tickOpts.display && this.ticks.length) { const { first, last, widest, highest } = this._getLabelSizes(); const tickPadding = tickOpts.padding * 2; const angleRadians = toRadians(this.labelRotation); const cos = Math.cos(angleRadians); const sin = Math.sin(angleRadians); if (isHorizontal) { const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height; minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding); } else { const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height; minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding); } this._calculatePadding(first, last, sin, cos); } } this._handleMargins(); if (isHorizontal) { this.width = this._length = chart.width - this._margins.left - this._margins.right; this.height = minSize.height; } else { this.width = minSize.width; this.height = this._length = chart.height - this._margins.top - this._margins.bottom; } } _calculatePadding(first, last, sin, cos) { const { ticks: { align, padding }, position } = this.options; const isRotated = this.labelRotation !== 0; const labelsBelowTicks = position !== "top" && this.axis === "x"; if (this.isHorizontal()) { const offsetLeft = this.getPixelForTick(0) - this.left; const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1); let paddingLeft = 0; let paddingRight = 0; if (isRotated) { if (labelsBelowTicks) { paddingLeft = cos * first.width; paddingRight = sin * last.height; } else { paddingLeft = sin * first.height; paddingRight = cos * last.width; } } else if (align === "start") { paddingRight = last.width; } else if (align === "end") { paddingLeft = first.width; } else if (align !== "inner") { paddingLeft = first.width / 2; paddingRight = last.width / 2; } this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0); this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0); } else { let paddingTop = last.height / 2; let paddingBottom = first.height / 2; if (align === "start") { paddingTop = 0; paddingBottom = first.height; } else if (align === "end") { paddingTop = last.height; paddingBottom = 0; } this.paddingTop = paddingTop + padding; this.paddingBottom = paddingBottom + padding; } } _handleMargins() { if (this._margins) { this._margins.left = Math.max(this.paddingLeft, this._margins.left); this._margins.top = Math.max(this.paddingTop, this._margins.top); this._margins.right = Math.max(this.paddingRight, this._margins.right); this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom); } } afterFit() { callback(this.options.afterFit, [ this ]); } isHorizontal() { const { axis, position } = this.options; return position === "top" || position === "bottom" || axis === "x"; } isFullSize() { return this.options.fullSize; } _convertTicksToLabels(ticks) { this.beforeTickToLabelConversion(); this.generateTickLabels(ticks); let i2, ilen; for (i2 = 0, ilen = ticks.length; i2 < ilen; i2++) { if (isNullOrUndef(ticks[i2].label)) { ticks.splice(i2, 1); ilen--; i2--; } } this.afterTickToLabelConversion(); } _getLabelSizes() { let labelSizes = this._labelSizes; if (!labelSizes) { const sampleSize = this.options.ticks.sampleSize; let ticks = this.ticks; if (sampleSize < ticks.length) { ticks = sample(ticks, sampleSize); } this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit); } return labelSizes; } _computeLabelSizes(ticks, length, maxTicksLimit) { const { ctx, _longestTextCache: caches } = this; const widths = []; const heights = []; const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit)); let widestLabelSize = 0; let highestLabelSize = 0; let i2, j2, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; for (i2 = 0; i2 < length; i2 += increment) { label = ticks[i2].label; tickFont = this._resolveTickFontOptions(i2); ctx.font = fontString = tickFont.string; cache = caches[fontString] = caches[fontString] || { data: {}, gc: [] }; lineHeight = tickFont.lineHeight; width = height = 0; if (!isNullOrUndef(label) && !isArray(label)) { width = _measureText(ctx, cache.data, cache.gc, width, label); height = lineHeight; } else if (isArray(label)) { for (j2 = 0, jlen = label.length; j2 < jlen; ++j2) { nestedLabel = label[j2]; if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) { width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel); height += lineHeight; } } } widths.push(width); heights.push(height); widestLabelSize = Math.max(width, widestLabelSize); highestLabelSize = Math.max(height, highestLabelSize); } garbageCollect(caches, length); const widest = widths.indexOf(widestLabelSize); const highest = heights.indexOf(highestLabelSize); const valueAt = (idx) => ({ width: widths[idx] || 0, height: heights[idx] || 0 }); return { first: valueAt(0), last: valueAt(length - 1), widest: valueAt(widest), highest: valueAt(highest), widths, heights }; } getLabelForValue(value) { return value; } getPixelForValue(value, index) { return NaN; } getValueForPixel(pixel) { } getPixelForTick(index) { const ticks = this.ticks; if (index < 0 || index > ticks.length - 1) { return null; } return this.getPixelForValue(ticks[index].value); } getPixelForDecimal(decimal) { if (this._reversePixels) { decimal = 1 - decimal; } const pixel = this._startPixel + decimal * this._length; return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel); } getDecimalForPixel(pixel) { const decimal = (pixel - this._startPixel) / this._length; return this._reversePixels ? 1 - decimal : decimal; } getBasePixel() { return this.getPixelForValue(this.getBaseValue()); } getBaseValue() { const { min, max } = this; return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0; } getContext(index) { const ticks = this.ticks || []; if (index >= 0 && index < ticks.length) { const tick = ticks[index]; return tick.$context || (tick.$context = createTickContext(this.getContext(), index, tick)); } return this.$context || (this.$context = createScaleContext(this.chart.getContext(), this)); } _tickSize() { const optionTicks = this.options.ticks; const rot = toRadians(this.labelRotation); const cos = Math.abs(Math.cos(rot)); const sin = Math.abs(Math.sin(rot)); const labelSizes = this._getLabelSizes(); const padding = optionTicks.autoSkipPadding || 0; const w2 = labelSizes ? labelSizes.widest.width + padding : 0; const h6 = labelSizes ? labelSizes.highest.height + padding : 0; return this.isHorizontal() ? h6 * cos > w2 * sin ? w2 / cos : h6 / sin : h6 * sin < w2 * cos ? h6 / cos : w2 / sin; } _isVisible() { const display = this.options.display; if (display !== "auto") { return !!display; } return this.getMatchingVisibleMetas().length > 0; } _computeGridLineItems(chartArea) { const axis = this.axis; const chart = this.chart; const options = this.options; const { grid, position, border } = options; const offset = grid.offset; const isHorizontal = this.isHorizontal(); const ticks = this.ticks; const ticksLength = ticks.length + (offset ? 1 : 0); const tl = getTickMarkLength(grid); const items = []; const borderOpts = border.setContext(this.getContext()); const axisWidth = borderOpts.display ? borderOpts.width : 0; const axisHalfWidth = axisWidth / 2; const alignBorderValue = function(pixel) { return _alignPixel(chart, pixel, axisWidth); }; let borderValue, i2, lineValue, alignedLineValue; let tx1, ty1, tx2, ty2, x1, y1, x2, y2; if (position === "top") { borderValue = alignBorderValue(this.bottom); ty1 = this.bottom - tl; ty2 = borderValue - axisHalfWidth; y1 = alignBorderValue(chartArea.top) + axisHalfWidth; y2 = chartArea.bottom; } else if (position === "bottom") { borderValue = alignBorderValue(this.top); y1 = chartArea.top; y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth; ty1 = borderValue + axisHalfWidth; ty2 = this.top + tl; } else if (position === "left") { borderValue = alignBorderValue(this.right); tx1 = this.right - tl; tx2 = borderValue - axisHalfWidth; x1 = alignBorderValue(chartArea.left) + axisHalfWidth; x2 = chartArea.right; } else if (position === "right") { borderValue = alignBorderValue(this.left); x1 = chartArea.left; x2 = alignBorderValue(chartArea.right) - axisHalfWidth; tx1 = borderValue + axisHalfWidth; tx2 = this.left + tl; } else if (axis === "x") { if (position === "center") { borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5); } else if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); } y1 = chartArea.top; y2 = chartArea.bottom; ty1 = borderValue + axisHalfWidth; ty2 = ty1 + tl; } else if (axis === "y") { if (position === "center") { borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2); } else if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); } tx1 = borderValue - axisHalfWidth; tx2 = tx1 - tl; x1 = chartArea.left; x2 = chartArea.right; } const limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength); const step = Math.max(1, Math.ceil(ticksLength / limit)); for (i2 = 0; i2 < ticksLength; i2 += step) { const context = this.getContext(i2); const optsAtIndex = grid.setContext(context); const optsAtIndexBorder = border.setContext(context); const lineWidth = optsAtIndex.lineWidth; const lineColor = optsAtIndex.color; const borderDash = optsAtIndexBorder.dash || []; const borderDashOffset = optsAtIndexBorder.dashOffset; const tickWidth = optsAtIndex.tickWidth; const tickColor = optsAtIndex.tickColor; const tickBorderDash = optsAtIndex.tickBorderDash || []; const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset; lineValue = getPixelForGridLine(this, i2, offset); if (lineValue === void 0) { continue; } alignedLineValue = _alignPixel(chart, lineValue, lineWidth); if (isHorizontal) { tx1 = tx2 = x1 = x2 = alignedLineValue; } else { ty1 = ty2 = y1 = y2 = alignedLineValue; } items.push({ tx1, ty1, tx2, ty2, x1, y1, x2, y2, width: lineWidth, color: lineColor, borderDash, borderDashOffset, tickWidth, tickColor, tickBorderDash, tickBorderDashOffset }); } this._ticksLength = ticksLength; this._borderValue = borderValue; return items; } _computeLabelItems(chartArea) { const axis = this.axis; const options = this.options; const { position, ticks: optionTicks } = options; const isHorizontal = this.isHorizontal(); const ticks = this.ticks; const { align, crossAlign, padding, mirror } = optionTicks; const tl = getTickMarkLength(options.grid); const tickAndPadding = tl + padding; const hTickAndPadding = mirror ? -padding : tickAndPadding; const rotation = -toRadians(this.labelRotation); const items = []; let i2, ilen, tick, label, x2, y2, textAlign, pixel, font, lineHeight, lineCount, textOffset; let textBaseline = "middle"; if (position === "top") { y2 = this.bottom - hTickAndPadding; textAlign = this._getXAxisLabelAlignment(); } else if (position === "bottom") { y2 = this.top + hTickAndPadding; textAlign = this._getXAxisLabelAlignment(); } else if (position === "left") { const ret = this._getYAxisLabelAlignment(tl); textAlign = ret.textAlign; x2 = ret.x; } else if (position === "right") { const ret = this._getYAxisLabelAlignment(tl); textAlign = ret.textAlign; x2 = ret.x; } else if (axis === "x") { if (position === "center") { y2 = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding; } else if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; y2 = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding; } textAlign = this._getXAxisLabelAlignment(); } else if (axis === "y") { if (position === "center") { x2 = (chartArea.left + chartArea.right) / 2 - tickAndPadding; } else if (isObject(position)) { const positionAxisID = Object.keys(position)[0]; const value = position[positionAxisID]; x2 = this.chart.scales[positionAxisID].getPixelForValue(value); } textAlign = this._getYAxisLabelAlignment(tl).textAlign; } if (axis === "y") { if (align === "start") { textBaseline = "top"; } else if (align === "end") { textBaseline = "bottom"; } } const labelSizes = this._getLabelSizes(); for (i2 = 0, ilen = ticks.length; i2 < ilen; ++i2) { tick = ticks[i2]; label = tick.label; const optsAtIndex = optionTicks.setContext(this.getContext(i2)); pixel = this.getPixelForTick(i2) + optionTicks.labelOffset; font = this._resolveTickFontOptions(i2); lineHeight = font.lineHeight; lineCount = isArray(label) ? label.length : 1; const halfCount = lineCount / 2; const color2 = optsAtIndex.color; const strokeColor = optsAtIndex.textStrokeColor; const strokeWidth = optsAtIndex.textStrokeWidth; let tickTextAlign = textAlign; if (isHorizontal) { x2 = pixel; if (textAlign === "inner") { if (i2 === ilen - 1) { tickTextAlign = !this.options.reverse ? "right" : "left"; } else if (i2 === 0) { tickTextAlign = !this.options.reverse ? "left" : "right"; } else { tickTextAlign = "center"; } } if (position === "top") { if (crossAlign === "near" || rotation !== 0) { textOffset = -lineCount * lineHeight + lineHeight / 2; } else if (crossAlign === "center") { textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight; } else { textOffset = -labelSizes.highest.height + lineHeight / 2; } } else { if (crossAlign === "near" || rotation !== 0) { textOffset = lineHeight / 2; } else if (crossAlign === "center") { textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight; } else { textOffset = labelSizes.highest.height - lineCount * lineHeight; } } if (mirror) { textOffset *= -1; } if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) { x2 += lineHeight / 2 * Math.sin(rotation); } } else { y2 = pixel; textOffset = (1 - lineCount) * lineHeight / 2; } let backdrop; if (optsAtIndex.showLabelBackdrop) { const labelPadding = toPadding(optsAtIndex.backdropPadding); const height = labelSizes.heights[i2]; const width = labelSizes.widths[i2]; let top = textOffset - labelPadding.top; let left = 0 - labelPadding.left; switch (textBaseline) { case "middle": top -= height / 2; break; case "bottom": top -= height; break; } switch (textAlign) { case "center": left -= width / 2; break; case "right": left -= width; break; case "inner": if (i2 === ilen - 1) { left -= width; } else if (i2 > 0) { left -= width / 2; } break; } backdrop = { left, top, width: width + labelPadding.width, height: height + labelPadding.height, color: optsAtIndex.backdropColor }; } items.push({ label, font, textOffset, options: { rotation, color: color2, strokeColor, strokeWidth, textAlign: tickTextAlign, textBaseline, translation: [ x2, y2 ], backdrop } }); } return items; } _getXAxisLabelAlignment() { const { position, ticks } = this.options; const rotation = -toRadians(this.labelRotation); if (rotation) { return position === "top" ? "left" : "right"; } let align = "center"; if (ticks.align === "start") { align = "left"; } else if (ticks.align === "end") { align = "right"; } else if (ticks.align === "inner") { align = "inner"; } return align; } _getYAxisLabelAlignment(tl) { const { position, ticks: { crossAlign, mirror, padding } } = this.options; const labelSizes = this._getLabelSizes(); const tickAndPadding = tl + padding; const widest = labelSizes.widest.width; let textAlign; let x2; if (position === "left") { if (mirror) { x2 = this.right + padding; if (crossAlign === "near") { textAlign = "left"; } else if (crossAlign === "center") { textAlign = "center"; x2 += widest / 2; } else { textAlign = "right"; x2 += widest; } } else { x2 = this.right - tickAndPadding; if (crossAlign === "near") { textAlign = "right"; } else if (crossAlign === "center") { textAlign = "center"; x2 -= widest / 2; } else { textAlign = "left"; x2 = this.left; } } } else if (position === "right") { if (mirror) { x2 = this.left + padding; if (crossAlign === "near") { textAlign = "right"; } else if (crossAlign === "center") { textAlign = "center"; x2 -= widest / 2; } else { textAlign = "left"; x2 -= widest; } } else { x2 = this.left + tickAndPadding; if (crossAlign === "near") { textAlign = "left"; } else if (crossAlign === "center") { textAlign = "center"; x2 += widest / 2; } else { textAlign = "right"; x2 = this.right; } } } else { textAlign = "right"; } return { textAlign, x: x2 }; } _computeLabelArea() { if (this.options.ticks.mirror) { return; } const chart = this.chart; const position = this.options.position; if (position === "left" || position === "right") { return { top: 0, left: this.left, bottom: chart.height, right: this.right }; } if (position === "top" || position === "bottom") { return { top: this.top, left: 0, bottom: this.bottom, right: chart.width }; } } drawBackground() { const { ctx, options: { backgroundColor }, left, top, width, height } = this; if (backgroundColor) { ctx.save(); ctx.fillStyle = backgroundColor; ctx.fillRect(left, top, width, height); ctx.restore(); } } getLineWidthForValue(value) { const grid = this.options.grid; if (!this._isVisible() || !grid.display) { return 0; } const ticks = this.ticks; const index = ticks.findIndex((t3) => t3.value === value); if (index >= 0) { const opts = grid.setContext(this.getContext(index)); return opts.lineWidth; } return 0; } drawGrid(chartArea) { const grid = this.options.grid; const ctx = this.ctx; const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea)); let i2, ilen; const drawLine = (p1, p2, style) => { if (!style.width || !style.color) { return; } ctx.save(); ctx.lineWidth = style.width; ctx.strokeStyle = style.color; ctx.setLineDash(style.borderDash || []); ctx.lineDashOffset = style.borderDashOffset; ctx.beginPath(); ctx.moveTo(p1.x, p1.y); ctx.lineTo(p2.x, p2.y); ctx.stroke(); ctx.restore(); }; if (grid.display) { for (i2 = 0, ilen = items.length; i2 < ilen; ++i2) { const item = items[i2]; if (grid.drawOnChartArea) { drawLine({ x: item.x1, y: item.y1 }, { x: item.x2, y: item.y2 }, item); } if (grid.drawTicks) { drawLine({ x: item.tx1, y: item.ty1 }, { x: item.tx2, y: item.ty2 }, { color: item.tickColor, width: item.tickWidth, borderDash: item.tickBorderDash, borderDashOffset: item.tickBorderDashOffset }); } } } } drawBorder() { const { chart, ctx, options: { border, grid } } = this; const borderOpts = border.setContext(this.getContext()); const axisWidth = border.display ? borderOpts.width : 0; if (!axisWidth) { return; } const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth; const borderValue = this._borderValue; let x1, x2, y1, y2; if (this.isHorizontal()) { x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2; x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2; y1 = y2 = borderValue; } else { y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2; y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2; x1 = x2 = borderValue; } ctx.save(); ctx.lineWidth = borderOpts.width; ctx.strokeStyle = borderOpts.color; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); ctx.restore(); } drawLabels(chartArea) { const optionTicks = this.options.ticks; if (!optionTicks.display) { return; } const ctx = this.ctx; const area = this._computeLabelArea(); if (area) { clipArea(ctx, area); } const items = this.getLabelItems(chartArea); for (const item of items) { const renderTextOptions = item.options; const tickFont = item.font; const label = item.label; const y2 = item.textOffset; renderText(ctx, label, 0, y2, tickFont, renderTextOptions); } if (area) { unclipArea(ctx); } } drawTitle() { const { ctx, options: { position, title, reverse } } = this; if (!title.display) { return; } const font = toFont(title.font); const padding = toPadding(title.padding); const align = title.align; let offset = font.lineHeight / 2; if (position === "bottom" || position === "center" || isObject(position)) { offset += padding.bottom; if (isArray(title.text)) { offset += font.lineHeight * (title.text.length - 1); } } else { offset += padding.top; } const { titleX, titleY, maxWidth, rotation } = titleArgs(this, offset, position, align); renderText(ctx, title.text, 0, 0, font, { color: title.color, maxWidth, rotation, textAlign: titleAlign(align, position, reverse), textBaseline: "middle", translation: [ titleX, titleY ] }); } draw(chartArea) { if (!this._isVisible()) { return; } this.drawBackground(); this.drawGrid(chartArea); this.drawBorder(); this.drawTitle(); this.drawLabels(chartArea); } _layers() { const opts = this.options; const tz = opts.ticks && opts.ticks.z || 0; const gz = valueOrDefault(opts.grid && opts.grid.z, -1); const bz = valueOrDefault(opts.border && opts.border.z, 0); if (!this._isVisible() || this.draw !== _Scale.prototype.draw) { return [ { z: tz, draw: (chartArea) => { this.draw(chartArea); } } ]; } return [ { z: gz, draw: (chartArea) => { this.drawBackground(); this.drawGrid(chartArea); this.drawTitle(); } }, { z: bz, draw: () => { this.drawBorder(); } }, { z: tz, draw: (chartArea) => { this.drawLabels(chartArea); } } ]; } getMatchingVisibleMetas(type) { const metas = this.chart.getSortedVisibleDatasetMetas(); const axisID = this.axis + "AxisID"; const result = []; let i2, ilen; for (i2 = 0, ilen = metas.length; i2 < ilen; ++i2) { const meta = metas[i2]; if (meta[axisID] === this.id && (!type || meta.type === type)) { result.push(meta); } } return result; } _resolveTickFontOptions(index) { const opts = this.options.ticks.setContext(this.getContext(index)); return toFont(opts.font); } _maxDigits() { const fontSize = this._resolveTickFontOptions(0).lineHeight; return (this.isHorizontal() ? this.width : this.height) / fontSize; } }; var TypedRegistry = class { constructor(type, scope, override) { this.type = type; this.scope = scope; this.override = override; this.items = /* @__PURE__ */ Object.create(null); } isForType(type) { return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype); } register(item) { const proto = Object.getPrototypeOf(item); let parentScope; if (isIChartComponent(proto)) { parentScope = this.register(proto); } const items = this.items; const id = item.id; const scope = this.scope + "." + id; if (!id) { throw new Error("class does not have id: " + item); } if (id in items) { return scope; } items[id] = item; registerDefaults(item, scope, parentScope); if (this.override) { defaults2.override(item.id, item.overrides); } return scope; } get(id) { return this.items[id]; } unregister(item) { const items = this.items; const id = item.id; const scope = this.scope; if (id in items) { delete items[id]; } if (scope && id in defaults2[scope]) { delete defaults2[scope][id]; if (this.override) { delete overrides[id]; } } } }; function registerDefaults(item, scope, parentScope) { const itemDefaults = merge(/* @__PURE__ */ Object.create(null), [ parentScope ? defaults2.get(parentScope) : {}, defaults2.get(scope), item.defaults ]); defaults2.set(scope, itemDefaults); if (item.defaultRoutes) { routeDefaults(scope, item.defaultRoutes); } if (item.descriptors) { defaults2.describe(scope, item.descriptors); } } function routeDefaults(scope, routes) { Object.keys(routes).forEach((property) => { const propertyParts = property.split("."); const sourceName = propertyParts.pop(); const sourceScope = [ scope ].concat(propertyParts).join("."); const parts = routes[property].split("."); const targetName = parts.pop(); const targetScope = parts.join("."); defaults2.route(sourceScope, sourceName, targetScope, targetName); }); } function isIChartComponent(proto) { return "id" in proto && "defaults" in proto; } var Registry = class { constructor() { this.controllers = new TypedRegistry(DatasetController, "datasets", true); this.elements = new TypedRegistry(Element, "elements"); this.plugins = new TypedRegistry(Object, "plugins"); this.scales = new TypedRegistry(Scale, "scales"); this._typedRegistries = [ this.controllers, this.scales, this.elements ]; } add(...args) { this._each("register", args); } remove(...args) { this._each("unregister", args); } addControllers(...args) { this._each("register", args, this.controllers); } addElements(...args) { this._each("register", args, this.elements); } addPlugins(...args) { this._each("register", args, this.plugins); } addScales(...args) { this._each("register", args, this.scales); } getController(id) { return this._get(id, this.controllers, "controller"); } getElement(id) { return this._get(id, this.elements, "element"); } getPlugin(id) { return this._get(id, this.plugins, "plugin"); } getScale(id) { return this._get(id, this.scales, "scale"); } removeControllers(...args) { this._each("unregister", args, this.controllers); } removeElements(...args) { this._each("unregister", args, this.elements); } removePlugins(...args) { this._each("unregister", args, this.plugins); } removeScales(...args) { this._each("unregister", args, this.scales); } _each(method, args, typedRegistry) { [ ...args ].forEach((arg) => { const reg = typedRegistry || this._getRegistryForType(arg); if (typedRegistry || reg.isForType(arg) || reg === this.plugins && arg.id) { this._exec(method, reg, arg); } else { each(arg, (item) => { const itemReg = typedRegistry || this._getRegistryForType(item); this._exec(method, itemReg, item); }); } }); } _exec(method, registry2, component) { const camelMethod = _capitalize(method); callback(component["before" + camelMethod], [], component); registry2[method](component); callback(component["after" + camelMethod], [], component); } _getRegistryForType(type) { for (let i2 = 0; i2 < this._typedRegistries.length; i2++) { const reg = this._typedRegistries[i2]; if (reg.isForType(type)) { return reg; } } return this.plugins; } _get(id, typedRegistry, type) { const item = typedRegistry.get(id); if (item === void 0) { throw new Error('"' + id + '" is not a registered ' + type + "."); } return item; } }; var registry = /* @__PURE__ */ new Registry(); var PluginService = class { constructor() { this._init = []; } notify(chart, hook, args, filter2) { if (hook === "beforeInit") { this._init = this._createDescriptors(chart, true); this._notify(this._init, chart, "install"); } const descriptors2 = filter2 ? this._descriptors(chart).filter(filter2) : this._descriptors(chart); const result = this._notify(descriptors2, chart, hook, args); if (hook === "afterDestroy") { this._notify(descriptors2, chart, "stop"); this._notify(this._init, chart, "uninstall"); } return result; } _notify(descriptors2, chart, hook, args) { args = args || {}; for (const descriptor of descriptors2) { const plugin = descriptor.plugin; const method = plugin[hook]; const params = [ chart, args, descriptor.options ]; if (callback(method, params, plugin) === false && args.cancelable) { return false; } } return true; } invalidate() { if (!isNullOrUndef(this._cache)) { this._oldCache = this._cache; this._cache = void 0; } } _descriptors(chart) { if (this._cache) { return this._cache; } const descriptors2 = this._cache = this._createDescriptors(chart); this._notifyStateChanges(chart); return descriptors2; } _createDescriptors(chart, all) { const config = chart && chart.config; const options = valueOrDefault(config.options && config.options.plugins, {}); const plugins = allPlugins(config); return options === false && !all ? [] : createDescriptors(chart, plugins, options, all); } _notifyStateChanges(chart) { const previousDescriptors = this._oldCache || []; const descriptors2 = this._cache; const diff = (a2, b2) => a2.filter((x2) => !b2.some((y2) => x2.plugin.id === y2.plugin.id)); this._notify(diff(previousDescriptors, descriptors2), chart, "stop"); this._notify(diff(descriptors2, previousDescriptors), chart, "start"); } }; function allPlugins(config) { const localIds = {}; const plugins = []; const keys = Object.keys(registry.plugins.items); for (let i2 = 0; i2 < keys.length; i2++) { plugins.push(registry.getPlugin(keys[i2])); } const local = config.plugins || []; for (let i2 = 0; i2 < local.length; i2++) { const plugin = local[i2]; if (plugins.indexOf(plugin) === -1) { plugins.push(plugin); localIds[plugin.id] = true; } } return { plugins, localIds }; } function getOpts(options, all) { if (!all && options === false) { return null; } if (options === true) { return {}; } return options; } function createDescriptors(chart, { plugins, localIds }, options, all) { const result = []; const context = chart.getContext(); for (const plugin of plugins) { const id = plugin.id; const opts = getOpts(options[id], all); if (opts === null) { continue; } result.push({ plugin, options: pluginOpts(chart.config, { plugin, local: localIds[id] }, opts, context) }); } return result; } function pluginOpts(config, { plugin, local }, opts, context) { const keys = config.pluginScopeKeys(plugin); const scopes = config.getOptionScopes(opts, keys); if (local && plugin.defaults) { scopes.push(plugin.defaults); } return config.createResolver(scopes, context, [ "" ], { scriptable: false, indexable: false, allKeys: true }); } function getIndexAxis(type, options) { const datasetDefaults = defaults2.datasets[type] || {}; const datasetOptions = (options.datasets || {})[type] || {}; return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || "x"; } function getAxisFromDefaultScaleID(id, indexAxis) { let axis = id; if (id === "_index_") { axis = indexAxis; } else if (id === "_value_") { axis = indexAxis === "x" ? "y" : "x"; } return axis; } function getDefaultScaleIDFromAxis(axis, indexAxis) { return axis === indexAxis ? "_index_" : "_value_"; } function idMatchesAxis(id) { if (id === "x" || id === "y" || id === "r") { return id; } } function axisFromPosition(position) { if (position === "top" || position === "bottom") { return "x"; } if (position === "left" || position === "right") { return "y"; } } function determineAxis(id, ...scaleOptions) { if (idMatchesAxis(id)) { return id; } for (const opts of scaleOptions) { const axis = opts.axis || axisFromPosition(opts.position) || id.length > 1 && idMatchesAxis(id[0].toLowerCase()); if (axis) { return axis; } } throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`); } function getAxisFromDataset(id, axis, dataset) { if (dataset[axis + "AxisID"] === id) { return { axis }; } } function retrieveAxisFromDatasets(id, config) { if (config.data && config.data.datasets) { const boundDs = config.data.datasets.filter((d2) => d2.xAxisID === id || d2.yAxisID === id); if (boundDs.length) { return getAxisFromDataset(id, "x", boundDs[0]) || getAxisFromDataset(id, "y", boundDs[0]); } } return {}; } function mergeScaleConfig(config, options) { const chartDefaults = overrides[config.type] || { scales: {} }; const configScales = options.scales || {}; const chartIndexAxis = getIndexAxis(config.type, options); const scales = /* @__PURE__ */ Object.create(null); Object.keys(configScales).forEach((id) => { const scaleConf = configScales[id]; if (!isObject(scaleConf)) { return console.error(`Invalid scale configuration for scale: ${id}`); } if (scaleConf._proxy) { return console.warn(`Ignoring resolver passed as options for scale: ${id}`); } const axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), defaults2.scales[scaleConf.type]); const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis); const defaultScaleOptions = chartDefaults.scales || {}; scales[id] = mergeIf(/* @__PURE__ */ Object.create(null), [ { axis }, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId] ]); }); config.data.datasets.forEach((dataset) => { const type = dataset.type || config.type; const indexAxis = dataset.indexAxis || getIndexAxis(type, options); const datasetDefaults = overrides[type] || {}; const defaultScaleOptions = datasetDefaults.scales || {}; Object.keys(defaultScaleOptions).forEach((defaultID) => { const axis = getAxisFromDefaultScaleID(defaultID, indexAxis); const id = dataset[axis + "AxisID"] || axis; scales[id] = scales[id] || /* @__PURE__ */ Object.create(null); mergeIf(scales[id], [ { axis }, configScales[id], defaultScaleOptions[defaultID] ]); }); }); Object.keys(scales).forEach((key) => { const scale = scales[key]; mergeIf(scale, [ defaults2.scales[scale.type], defaults2.scale ]); }); return scales; } function initOptions(config) { const options = config.options || (config.options = {}); options.plugins = valueOrDefault(options.plugins, {}); options.scales = mergeScaleConfig(config, options); } function initData(data) { data = data || {}; data.datasets = data.datasets || []; data.labels = data.labels || []; return data; } function initConfig(config) { config = config || {}; config.data = initData(config.data); initOptions(config); return config; } var keyCache = /* @__PURE__ */ new Map(); var keysCached = /* @__PURE__ */ new Set(); function cachedKeys(cacheKey, generate) { let keys = keyCache.get(cacheKey); if (!keys) { keys = generate(); keyCache.set(cacheKey, keys); keysCached.add(keys); } return keys; } var addIfFound = (set2, obj, key) => { const opts = resolveObjectKey(obj, key); if (opts !== void 0) { set2.add(opts); } }; var Config = class { constructor(config) { this._config = initConfig(config); this._scopeCache = /* @__PURE__ */ new Map(); this._resolverCache = /* @__PURE__ */ new Map(); } get platform() { return this._config.platform; } get type() { return this._config.type; } set type(type) { this._config.type = type; } get data() { return this._config.data; } set data(data) { this._config.data = initData(data); } get options() { return this._config.options; } set options(options) { this._config.options = options; } get plugins() { return this._config.plugins; } update() { const config = this._config; this.clearCache(); initOptions(config); } clearCache() { this._scopeCache.clear(); this._resolverCache.clear(); } datasetScopeKeys(datasetType) { return cachedKeys(datasetType, () => [ [ `datasets.${datasetType}`, "" ] ]); } datasetAnimationScopeKeys(datasetType, transition) { return cachedKeys(`${datasetType}.transition.${transition}`, () => [ [ `datasets.${datasetType}.transitions.${transition}`, `transitions.${transition}` ], [ `datasets.${datasetType}`, "" ] ]); } datasetElementScopeKeys(datasetType, elementType) { return cachedKeys(`${datasetType}-${elementType}`, () => [ [ `datasets.${datasetType}.elements.${elementType}`, `datasets.${datasetType}`, `elements.${elementType}`, "" ] ]); } pluginScopeKeys(plugin) { const id = plugin.id; const type = this.type; return cachedKeys(`${type}-plugin-${id}`, () => [ [ `plugins.${id}`, ...plugin.additionalOptionScopes || [] ] ]); } _cachedScopes(mainScope, resetCache) { const _scopeCache = this._scopeCache; let cache = _scopeCache.get(mainScope); if (!cache || resetCache) { cache = /* @__PURE__ */ new Map(); _scopeCache.set(mainScope, cache); } return cache; } getOptionScopes(mainScope, keyLists, resetCache) { const { options, type } = this; const cache = this._cachedScopes(mainScope, resetCache); const cached = cache.get(keyLists); if (cached) { return cached; } const scopes = /* @__PURE__ */ new Set(); keyLists.forEach((keys) => { if (mainScope) { scopes.add(mainScope); keys.forEach((key) => addIfFound(scopes, mainScope, key)); } keys.forEach((key) => addIfFound(scopes, options, key)); keys.forEach((key) => addIfFound(scopes, overrides[type] || {}, key)); keys.forEach((key) => addIfFound(scopes, defaults2, key)); keys.forEach((key) => addIfFound(scopes, descriptors, key)); }); const array = Array.from(scopes); if (array.length === 0) { array.push(/* @__PURE__ */ Object.create(null)); } if (keysCached.has(keyLists)) { cache.set(keyLists, array); } return array; } chartOptionScopes() { const { options, type } = this; return [ options, overrides[type] || {}, defaults2.datasets[type] || {}, { type }, defaults2, descriptors ]; } resolveNamedOptions(scopes, names2, context, prefixes = [ "" ]) { const result = { $shared: true }; const { resolver, subPrefixes } = getResolver(this._resolverCache, scopes, prefixes); let options = resolver; if (needContext(resolver, names2)) { result.$shared = false; context = isFunction(context) ? context() : context; const subResolver = this.createResolver(scopes, context, subPrefixes); options = _attachContext(resolver, context, subResolver); } for (const prop of names2) { result[prop] = options[prop]; } return result; } createResolver(scopes, context, prefixes = [ "" ], descriptorDefaults) { const { resolver } = getResolver(this._resolverCache, scopes, prefixes); return isObject(context) ? _attachContext(resolver, context, void 0, descriptorDefaults) : resolver; } }; function getResolver(resolverCache, scopes, prefixes) { let cache = resolverCache.get(scopes); if (!cache) { cache = /* @__PURE__ */ new Map(); resolverCache.set(scopes, cache); } const cacheKey = prefixes.join(); let cached = cache.get(cacheKey); if (!cached) { const resolver = _createResolver(scopes, prefixes); cached = { resolver, subPrefixes: prefixes.filter((p2) => !p2.toLowerCase().includes("hover")) }; cache.set(cacheKey, cached); } return cached; } var hasFunction = (value) => isObject(value) && Object.getOwnPropertyNames(value).some((key) => isFunction(value[key])); function needContext(proxy, names2) { const { isScriptable, isIndexable } = _descriptors(proxy); for (const prop of names2) { const scriptable = isScriptable(prop); const indexable = isIndexable(prop); const value = (indexable || scriptable) && proxy[prop]; if (scriptable && (isFunction(value) || hasFunction(value)) || indexable && isArray(value)) { return true; } } return false; } var version = "4.4.4"; var KNOWN_POSITIONS = [ "top", "bottom", "left", "right", "chartArea" ]; function positionIsHorizontal(position, axis) { return position === "top" || position === "bottom" || KNOWN_POSITIONS.indexOf(position) === -1 && axis === "x"; } function compare2Level(l1, l2) { return function(a2, b2) { return a2[l1] === b2[l1] ? a2[l2] - b2[l2] : a2[l1] - b2[l1]; }; } function onAnimationsComplete(context) { const chart = context.chart; const animationOptions = chart.options.animation; chart.notifyPlugins("afterRender"); callback(animationOptions && animationOptions.onComplete, [ context ], chart); } function onAnimationProgress(context) { const chart = context.chart; const animationOptions = chart.options.animation; callback(animationOptions && animationOptions.onProgress, [ context ], chart); } function getCanvas(item) { if (_isDomSupported() && typeof item === "string") { item = document.getElementById(item); } else if (item && item.length) { item = item[0]; } if (item && item.canvas) { item = item.canvas; } return item; } var instances = {}; var getChart = (key) => { const canvas = getCanvas(key); return Object.values(instances).filter((c2) => c2.canvas === canvas).pop(); }; function moveNumericKeys(obj, start, move) { const keys = Object.keys(obj); for (const key of keys) { const intKey = +key; if (intKey >= start) { const value = obj[key]; delete obj[key]; if (move > 0 || intKey > start) { obj[intKey + move] = value; } } } } function determineLastEvent(e2, lastEvent, inChartArea, isClick) { if (!inChartArea || e2.type === "mouseout") { return null; } if (isClick) { return lastEvent; } return e2; } function getSizeForArea(scale, chartArea, field) { return scale.options.clip ? scale[field] : chartArea[field]; } function getDatasetArea(meta, chartArea) { const { xScale, yScale } = meta; if (xScale && yScale) { return { left: getSizeForArea(xScale, chartArea, "left"), right: getSizeForArea(xScale, chartArea, "right"), top: getSizeForArea(yScale, chartArea, "top"), bottom: getSizeForArea(yScale, chartArea, "bottom") }; } return chartArea; } var Chart = class { static register(...items) { registry.add(...items); invalidatePlugins(); } static unregister(...items) { registry.remove(...items); invalidatePlugins(); } constructor(item, userConfig) { const config = this.config = new Config(userConfig); const initialCanvas = getCanvas(item); const existingChart = getChart(initialCanvas); if (existingChart) { throw new Error("Canvas is already in use. Chart with ID '" + existingChart.id + "' must be destroyed before the canvas with ID '" + existingChart.canvas.id + "' can be reused."); } const options = config.createResolver(config.chartOptionScopes(), this.getContext()); this.platform = new (config.platform || _detectPlatform(initialCanvas))(); this.platform.updateConfig(config); const context = this.platform.acquireContext(initialCanvas, options.aspectRatio); const canvas = context && context.canvas; const height = canvas && canvas.height; const width = canvas && canvas.width; this.id = uid(); this.ctx = context; this.canvas = canvas; this.width = width; this.height = height; this._options = options; this._aspectRatio = this.aspectRatio; this._layers = []; this._metasets = []; this._stacks = void 0; this.boxes = []; this.currentDevicePixelRatio = void 0; this.chartArea = void 0; this._active = []; this._lastEvent = void 0; this._listeners = {}; this._responsiveListeners = void 0; this._sortedMetasets = []; this.scales = {}; this._plugins = new PluginService(); this.$proxies = {}; this._hiddenIndices = {}; this.attached = false; this._animationsDisabled = void 0; this.$context = void 0; this._doResize = debounce((mode) => this.update(mode), options.resizeDelay || 0); this._dataChanges = []; instances[this.id] = this; if (!context || !canvas) { console.error("Failed to create chart: can't acquire context from the given item"); return; } animator.listen(this, "complete", onAnimationsComplete); animator.listen(this, "progress", onAnimationProgress); this._initialize(); if (this.attached) { this.update(); } } get aspectRatio() { const { options: { aspectRatio, maintainAspectRatio }, width, height, _aspectRatio } = this; if (!isNullOrUndef(aspectRatio)) { return aspectRatio; } if (maintainAspectRatio && _aspectRatio) { return _aspectRatio; } return height ? width / height : null; } get data() { return this.config.data; } set data(data) { this.config.data = data; } get options() { return this._options; } set options(options) { this.config.options = options; } get registry() { return registry; } _initialize() { this.notifyPlugins("beforeInit"); if (this.options.responsive) { this.resize(); } else { retinaScale(this, this.options.devicePixelRatio); } this.bindEvents(); this.notifyPlugins("afterInit"); return this; } clear() { clearCanvas(this.canvas, this.ctx); return this; } stop() { animator.stop(this); return this; } resize(width, height) { if (!animator.running(this)) { this._resize(width, height); } else { this._resizeBeforeDraw = { width, height }; } } _resize(width, height) { const options = this.options; const canvas = this.canvas; const aspectRatio = options.maintainAspectRatio && this.aspectRatio; const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio); const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio(); const mode = this.width ? "resize" : "attach"; this.width = newSize.width; this.height = newSize.height; this._aspectRatio = this.aspectRatio; if (!retinaScale(this, newRatio, true)) { return; } this.notifyPlugins("resize", { size: newSize }); callback(options.onResize, [ this, newSize ], this); if (this.attached) { if (this._doResize(mode)) { this.render(); } } } ensureScalesHaveIDs() { const options = this.options; const scalesOptions = options.scales || {}; each(scalesOptions, (axisOptions, axisID) => { axisOptions.id = axisID; }); } buildOrUpdateScales() { const options = this.options; const scaleOpts = options.scales; const scales = this.scales; const updated = Object.keys(scales).reduce((obj, id) => { obj[id] = false; return obj; }, {}); let items = []; if (scaleOpts) { items = items.concat(Object.keys(scaleOpts).map((id) => { const scaleOptions = scaleOpts[id]; const axis = determineAxis(id, scaleOptions); const isRadial = axis === "r"; const isHorizontal = axis === "x"; return { options: scaleOptions, dposition: isRadial ? "chartArea" : isHorizontal ? "bottom" : "left", dtype: isRadial ? "radialLinear" : isHorizontal ? "category" : "linear" }; })); } each(items, (item) => { const scaleOptions = item.options; const id = scaleOptions.id; const axis = determineAxis(id, scaleOptions); const scaleType = valueOrDefault(scaleOptions.type, item.dtype); if (scaleOptions.position === void 0 || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) { scaleOptions.position = item.dposition; } updated[id] = true; let scale = null; if (id in scales && scales[id].type === scaleType) { scale = scales[id]; } else { const scaleClass = registry.getScale(scaleType); scale = new scaleClass({ id, type: scaleType, ctx: this.ctx, chart: this }); scales[scale.id] = scale; } scale.init(scaleOptions, options); }); each(updated, (hasUpdated, id) => { if (!hasUpdated) { delete scales[id]; } }); each(scales, (scale) => { layouts.configure(this, scale, scale.options); layouts.addBox(this, scale); }); } _updateMetasets() { const metasets = this._metasets; const numData = this.data.datasets.length; const numMeta = metasets.length; metasets.sort((a2, b2) => a2.index - b2.index); if (numMeta > numData) { for (let i2 = numData; i2 < numMeta; ++i2) { this._destroyDatasetMeta(i2); } metasets.splice(numData, numMeta - numData); } this._sortedMetasets = metasets.slice(0).sort(compare2Level("order", "index")); } _removeUnreferencedMetasets() { const { _metasets: metasets, data: { datasets } } = this; if (metasets.length > datasets.length) { delete this._stacks; } metasets.forEach((meta, index) => { if (datasets.filter((x2) => x2 === meta._dataset).length === 0) { this._destroyDatasetMeta(index); } }); } buildOrUpdateControllers() { const newControllers = []; const datasets = this.data.datasets; let i2, ilen; this._removeUnreferencedMetasets(); for (i2 = 0, ilen = datasets.length; i2 < ilen; i2++) { const dataset = datasets[i2]; let meta = this.getDatasetMeta(i2); const type = dataset.type || this.config.type; if (meta.type && meta.type !== type) { this._destroyDatasetMeta(i2); meta = this.getDatasetMeta(i2); } meta.type = type; meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options); meta.order = dataset.order || 0; meta.index = i2; meta.label = "" + dataset.label; meta.visible = this.isDatasetVisible(i2); if (meta.controller) { meta.controller.updateIndex(i2); meta.controller.linkScales(); } else { const ControllerClass = registry.getController(type); const { datasetElementType, dataElementType } = defaults2.datasets[type]; Object.assign(ControllerClass, { dataElementType: registry.getElement(dataElementType), datasetElementType: datasetElementType && registry.getElement(datasetElementType) }); meta.controller = new ControllerClass(this, i2); newControllers.push(meta.controller); } } this._updateMetasets(); return newControllers; } _resetElements() { each(this.data.datasets, (dataset, datasetIndex) => { this.getDatasetMeta(datasetIndex).controller.reset(); }, this); } reset() { this._resetElements(); this.notifyPlugins("reset"); } update(mode) { const config = this.config; config.update(); const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext()); const animsDisabled = this._animationsDisabled = !options.animation; this._updateScales(); this._checkEventBindings(); this._updateHiddenIndices(); this._plugins.invalidate(); if (this.notifyPlugins("beforeUpdate", { mode, cancelable: true }) === false) { return; } const newControllers = this.buildOrUpdateControllers(); this.notifyPlugins("beforeElementsUpdate"); let minPadding = 0; for (let i2 = 0, ilen = this.data.datasets.length; i2 < ilen; i2++) { const { controller } = this.getDatasetMeta(i2); const reset2 = !animsDisabled && newControllers.indexOf(controller) === -1; controller.buildOrUpdateElements(reset2); minPadding = Math.max(+controller.getMaxOverflow(), minPadding); } minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0; this._updateLayout(minPadding); if (!animsDisabled) { each(newControllers, (controller) => { controller.reset(); }); } this._updateDatasets(mode); this.notifyPlugins("afterUpdate", { mode }); this._layers.sort(compare2Level("z", "_idx")); const { _active, _lastEvent } = this; if (_lastEvent) { this._eventHandler(_lastEvent, true); } else if (_active.length) { this._updateHoverStyles(_active, _active, true); } this.render(); } _updateScales() { each(this.scales, (scale) => { layouts.removeBox(this, scale); }); this.ensureScalesHaveIDs(); this.buildOrUpdateScales(); } _checkEventBindings() { const options = this.options; const existingEvents = new Set(Object.keys(this._listeners)); const newEvents = new Set(options.events); if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) { this.unbindEvents(); this.bindEvents(); } } _updateHiddenIndices() { const { _hiddenIndices } = this; const changes = this._getUniformDataChanges() || []; for (const { method, start, count } of changes) { const move = method === "_removeElements" ? -count : count; moveNumericKeys(_hiddenIndices, start, move); } } _getUniformDataChanges() { const _dataChanges = this._dataChanges; if (!_dataChanges || !_dataChanges.length) { return; } this._dataChanges = []; const datasetCount = this.data.datasets.length; const makeSet = (idx) => new Set(_dataChanges.filter((c2) => c2[0] === idx).map((c2, i2) => i2 + "," + c2.splice(1).join(","))); const changeSet = makeSet(0); for (let i2 = 1; i2 < datasetCount; i2++) { if (!setsEqual(changeSet, makeSet(i2))) { return; } } return Array.from(changeSet).map((c2) => c2.split(",")).map((a2) => ({ method: a2[1], start: +a2[2], count: +a2[3] })); } _updateLayout(minPadding) { if (this.notifyPlugins("beforeLayout", { cancelable: true }) === false) { return; } layouts.update(this, this.width, this.height, minPadding); const area = this.chartArea; const noArea = area.width <= 0 || area.height <= 0; this._layers = []; each(this.boxes, (box) => { if (noArea && box.position === "chartArea") { return; } if (box.configure) { box.configure(); } this._layers.push(...box._layers()); }, this); this._layers.forEach((item, index) => { item._idx = index; }); this.notifyPlugins("afterLayout"); } _updateDatasets(mode) { if (this.notifyPlugins("beforeDatasetsUpdate", { mode, cancelable: true }) === false) { return; } for (let i2 = 0, ilen = this.data.datasets.length; i2 < ilen; ++i2) { this.getDatasetMeta(i2).controller.configure(); } for (let i2 = 0, ilen = this.data.datasets.length; i2 < ilen; ++i2) { this._updateDataset(i2, isFunction(mode) ? mode({ datasetIndex: i2 }) : mode); } this.notifyPlugins("afterDatasetsUpdate", { mode }); } _updateDataset(index, mode) { const meta = this.getDatasetMeta(index); const args = { meta, index, mode, cancelable: true }; if (this.notifyPlugins("beforeDatasetUpdate", args) === false) { return; } meta.controller._update(mode); args.cancelable = false; this.notifyPlugins("afterDatasetUpdate", args); } render() { if (this.notifyPlugins("beforeRender", { cancelable: true }) === false) { return; } if (animator.has(this)) { if (this.attached && !animator.running(this)) { animator.start(this); } } else { this.draw(); onAnimationsComplete({ chart: this }); } } draw() { let i2; if (this._resizeBeforeDraw) { const { width, height } = this._resizeBeforeDraw; this._resizeBeforeDraw = null; this._resize(width, height); } this.clear(); if (this.width <= 0 || this.height <= 0) { return; } if (this.notifyPlugins("beforeDraw", { cancelable: true }) === false) { return; } const layers = this._layers; for (i2 = 0; i2 < layers.length && layers[i2].z <= 0; ++i2) { layers[i2].draw(this.chartArea); } this._drawDatasets(); for (; i2 < layers.length; ++i2) { layers[i2].draw(this.chartArea); } this.notifyPlugins("afterDraw"); } _getSortedDatasetMetas(filterVisible) { const metasets = this._sortedMetasets; const result = []; let i2, ilen; for (i2 = 0, ilen = metasets.length; i2 < ilen; ++i2) { const meta = metasets[i2]; if (!filterVisible || meta.visible) { result.push(meta); } } return result; } getSortedVisibleDatasetMetas() { return this._getSortedDatasetMetas(true); } _drawDatasets() { if (this.notifyPlugins("beforeDatasetsDraw", { cancelable: true }) === false) { return; } const metasets = this.getSortedVisibleDatasetMetas(); for (let i2 = metasets.length - 1; i2 >= 0; --i2) { this._drawDataset(metasets[i2]); } this.notifyPlugins("afterDatasetsDraw"); } _drawDataset(meta) { const ctx = this.ctx; const clip = meta._clip; const useClip = !clip.disabled; const area = getDatasetArea(meta, this.chartArea); const args = { meta, index: meta.index, cancelable: true }; if (this.notifyPlugins("beforeDatasetDraw", args) === false) { return; } if (useClip) { clipArea(ctx, { left: clip.left === false ? 0 : area.left - clip.left, right: clip.right === false ? this.width : area.right + clip.right, top: clip.top === false ? 0 : area.top - clip.top, bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom }); } meta.controller.draw(); if (useClip) { unclipArea(ctx); } args.cancelable = false; this.notifyPlugins("afterDatasetDraw", args); } isPointInArea(point) { return _isPointInArea(point, this.chartArea, this._minPadding); } getElementsAtEventForMode(e2, mode, options, useFinalPosition) { const method = Interaction.modes[mode]; if (typeof method === "function") { return method(this, e2, options, useFinalPosition); } return []; } getDatasetMeta(datasetIndex) { const dataset = this.data.datasets[datasetIndex]; const metasets = this._metasets; let meta = metasets.filter((x2) => x2 && x2._dataset === dataset).pop(); if (!meta) { meta = { type: null, data: [], dataset: null, controller: null, hidden: null, xAxisID: null, yAxisID: null, order: dataset && dataset.order || 0, index: datasetIndex, _dataset: dataset, _parsed: [], _sorted: false }; metasets.push(meta); } return meta; } getContext() { return this.$context || (this.$context = createContext(null, { chart: this, type: "chart" })); } getVisibleDatasetCount() { return this.getSortedVisibleDatasetMetas().length; } isDatasetVisible(datasetIndex) { const dataset = this.data.datasets[datasetIndex]; if (!dataset) { return false; } const meta = this.getDatasetMeta(datasetIndex); return typeof meta.hidden === "boolean" ? !meta.hidden : !dataset.hidden; } setDatasetVisibility(datasetIndex, visible) { const meta = this.getDatasetMeta(datasetIndex); meta.hidden = !visible; } toggleDataVisibility(index) { this._hiddenIndices[index] = !this._hiddenIndices[index]; } getDataVisibility(index) { return !this._hiddenIndices[index]; } _updateVisibility(datasetIndex, dataIndex, visible) { const mode = visible ? "show" : "hide"; const meta = this.getDatasetMeta(datasetIndex); const anims = meta.controller._resolveAnimations(void 0, mode); if (defined(dataIndex)) { meta.data[dataIndex].hidden = !visible; this.update(); } else { this.setDatasetVisibility(datasetIndex, visible); anims.update(meta, { visible }); this.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : void 0); } } hide(datasetIndex, dataIndex) { this._updateVisibility(datasetIndex, dataIndex, false); } show(datasetIndex, dataIndex) { this._updateVisibility(datasetIndex, dataIndex, true); } _destroyDatasetMeta(datasetIndex) { const meta = this._metasets[datasetIndex]; if (meta && meta.controller) { meta.controller._destroy(); } delete this._metasets[datasetIndex]; } _stop() { let i2, ilen; this.stop(); animator.remove(this); for (i2 = 0, ilen = this.data.datasets.length; i2 < ilen; ++i2) { this._destroyDatasetMeta(i2); } } destroy() { this.notifyPlugins("beforeDestroy"); const { canvas, ctx } = this; this._stop(); this.config.clearCache(); if (canvas) { this.unbindEvents(); clearCanvas(canvas, ctx); this.platform.releaseContext(ctx); this.canvas = null; this.ctx = null; } delete instances[this.id]; this.notifyPlugins("afterDestroy"); } toBase64Image(...args) { return this.canvas.toDataURL(...args); } bindEvents() { this.bindUserEvents(); if (this.options.responsive) { this.bindResponsiveEvents(); } else { this.attached = true; } } bindUserEvents() { const listeners = this._listeners; const platform = this.platform; const _add = (type, listener2) => { platform.addEventListener(this, type, listener2); listeners[type] = listener2; }; const listener = (e2, x2, y2) => { e2.offsetX = x2; e2.offsetY = y2; this._eventHandler(e2); }; each(this.options.events, (type) => _add(type, listener)); } bindResponsiveEvents() { if (!this._responsiveListeners) { this._responsiveListeners = {}; } const listeners = this._responsiveListeners; const platform = this.platform; const _add = (type, listener2) => { platform.addEventListener(this, type, listener2); listeners[type] = listener2; }; const _remove = (type, listener2) => { if (listeners[type]) { platform.removeEventListener(this, type, listener2); delete listeners[type]; } }; const listener = (width, height) => { if (this.canvas) { this.resize(width, height); } }; let detached; const attached = () => { _remove("attach", attached); this.attached = true; this.resize(); _add("resize", listener); _add("detach", detached); }; detached = () => { this.attached = false; _remove("resize", listener); this._stop(); this._resize(0, 0); _add("attach", attached); }; if (platform.isAttached(this.canvas)) { attached(); } else { detached(); } } unbindEvents() { each(this._listeners, (listener, type) => { this.platform.removeEventListener(this, type, listener); }); this._listeners = {}; each(this._responsiveListeners, (listener, type) => { this.platform.removeEventListener(this, type, listener); }); this._responsiveListeners = void 0; } updateHoverStyle(items, mode, enabled) { const prefix = enabled ? "set" : "remove"; let meta, item, i2, ilen; if (mode === "dataset") { meta = this.getDatasetMeta(items[0].datasetIndex); meta.controller["_" + prefix + "DatasetHoverStyle"](); } for (i2 = 0, ilen = items.length; i2 < ilen; ++i2) { item = items[i2]; const controller = item && this.getDatasetMeta(item.datasetIndex).controller; if (controller) { controller[prefix + "HoverStyle"](item.element, item.datasetIndex, item.index); } } } getActiveElements() { return this._active || []; } setActiveElements(activeElements) { const lastActive = this._active || []; const active = activeElements.map(({ datasetIndex, index }) => { const meta = this.getDatasetMeta(datasetIndex); if (!meta) { throw new Error("No dataset found at index " + datasetIndex); } return { datasetIndex, element: meta.data[index], index }; }); const changed = !_elementsEqual(active, lastActive); if (changed) { this._active = active; this._lastEvent = null; this._updateHoverStyles(active, lastActive); } } notifyPlugins(hook, args, filter2) { return this._plugins.notify(this, hook, args, filter2); } isPluginEnabled(pluginId) { return this._plugins._cache.filter((p2) => p2.plugin.id === pluginId).length === 1; } _updateHoverStyles(active, lastActive, replay) { const hoverOptions = this.options.hover; const diff = (a2, b2) => a2.filter((x2) => !b2.some((y2) => x2.datasetIndex === y2.datasetIndex && x2.index === y2.index)); const deactivated = diff(lastActive, active); const activated = replay ? active : diff(active, lastActive); if (deactivated.length) { this.updateHoverStyle(deactivated, hoverOptions.mode, false); } if (activated.length && hoverOptions.mode) { this.updateHoverStyle(activated, hoverOptions.mode, true); } } _eventHandler(e2, replay) { const args = { event: e2, replay, cancelable: true, inChartArea: this.isPointInArea(e2) }; const eventFilter = (plugin) => (plugin.options.events || this.options.events).includes(e2.native.type); if (this.notifyPlugins("beforeEvent", args, eventFilter) === false) { return; } const changed = this._handleEvent(e2, replay, args.inChartArea); args.cancelable = false; this.notifyPlugins("afterEvent", args, eventFilter); if (changed || args.changed) { this.render(); } return this; } _handleEvent(e2, replay, inChartArea) { const { _active: lastActive = [], options } = this; const useFinalPosition = replay; const active = this._getActiveElements(e2, lastActive, inChartArea, useFinalPosition); const isClick = _isClickEvent(e2); const lastEvent = determineLastEvent(e2, this._lastEvent, inChartArea, isClick); if (inChartArea) { this._lastEvent = null; callback(options.onHover, [ e2, active, this ], this); if (isClick) { callback(options.onClick, [ e2, active, this ], this); } } const changed = !_elementsEqual(active, lastActive); if (changed || replay) { this._active = active; this._updateHoverStyles(active, lastActive, replay); } this._lastEvent = lastEvent; return changed; } _getActiveElements(e2, lastActive, inChartArea, useFinalPosition) { if (e2.type === "mouseout") { return []; } if (!inChartArea) { return lastActive; } const hoverOptions = this.options.hover; return this.getElementsAtEventForMode(e2, hoverOptions.mode, hoverOptions, useFinalPosition); } }; __publicField(Chart, "defaults", defaults2); __publicField(Chart, "instances", instances); __publicField(Chart, "overrides", overrides); __publicField(Chart, "registry", registry); __publicField(Chart, "version", version); __publicField(Chart, "getChart", getChart); function invalidatePlugins() { return each(Chart.instances, (chart) => chart._plugins.invalidate()); } function clipArc(ctx, element, endAngle) { const { startAngle, pixelMargin, x: x2, y: y2, outerRadius, innerRadius } = element; let angleMargin = pixelMargin / outerRadius; ctx.beginPath(); ctx.arc(x2, y2, outerRadius, startAngle - angleMargin, endAngle + angleMargin); if (innerRadius > pixelMargin) { angleMargin = pixelMargin / innerRadius; ctx.arc(x2, y2, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true); } else { ctx.arc(x2, y2, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI); } ctx.closePath(); ctx.clip(); } function toRadiusCorners(value) { return _readValueToProps(value, [ "outerStart", "outerEnd", "innerStart", "innerEnd" ]); } function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) { const o2 = toRadiusCorners(arc.options.borderRadius); const halfThickness = (outerRadius - innerRadius) / 2; const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2); const computeOuterLimit = (val) => { const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2; return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit)); }; return { outerStart: computeOuterLimit(o2.outerStart), outerEnd: computeOuterLimit(o2.outerEnd), innerStart: _limitValue(o2.innerStart, 0, innerLimit), innerEnd: _limitValue(o2.innerEnd, 0, innerLimit) }; } function rThetaToXY(r2, theta, x2, y2) { return { x: x2 + r2 * Math.cos(theta), y: y2 + r2 * Math.sin(theta) }; } function pathArc(ctx, element, offset, spacing, end, circular) { const { x: x2, y: y2, startAngle: start, pixelMargin, innerRadius: innerR } = element; const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0); const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0; let spacingOffset = 0; const alpha2 = end - start; if (spacing) { const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0; const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0; const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2; const adjustedAngle = avNogSpacingRadius !== 0 ? alpha2 * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha2; spacingOffset = (alpha2 - adjustedAngle) / 2; } const beta = Math.max(1e-3, alpha2 * outerRadius - offset / PI) / outerRadius; const angleOffset = (alpha2 - beta) / 2; const startAngle = start + angleOffset + spacingOffset; const endAngle = end - angleOffset - spacingOffset; const { outerStart, outerEnd, innerStart, innerEnd } = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle); const outerStartAdjustedRadius = outerRadius - outerStart; const outerEndAdjustedRadius = outerRadius - outerEnd; const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius; const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius; const innerStartAdjustedRadius = innerRadius + innerStart; const innerEndAdjustedRadius = innerRadius + innerEnd; const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius; const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius; ctx.beginPath(); if (circular) { const outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2; ctx.arc(x2, y2, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle); ctx.arc(x2, y2, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle); if (outerEnd > 0) { const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x2, y2); ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI); } const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x2, y2); ctx.lineTo(p4.x, p4.y); if (innerEnd > 0) { const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x2, y2); ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI); } const innerMidAdjustedAngle = (endAngle - innerEnd / innerRadius + (startAngle + innerStart / innerRadius)) / 2; ctx.arc(x2, y2, innerRadius, endAngle - innerEnd / innerRadius, innerMidAdjustedAngle, true); ctx.arc(x2, y2, innerRadius, innerMidAdjustedAngle, startAngle + innerStart / innerRadius, true); if (innerStart > 0) { const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x2, y2); ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI); } const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x2, y2); ctx.lineTo(p8.x, p8.y); if (outerStart > 0) { const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x2, y2); ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle); } } else { ctx.moveTo(x2, y2); const outerStartX = Math.cos(outerStartAdjustedAngle) * outerRadius + x2; const outerStartY = Math.sin(outerStartAdjustedAngle) * outerRadius + y2; ctx.lineTo(outerStartX, outerStartY); const outerEndX = Math.cos(outerEndAdjustedAngle) * outerRadius + x2; const outerEndY = Math.sin(outerEndAdjustedAngle) * outerRadius + y2; ctx.lineTo(outerEndX, outerEndY); } ctx.closePath(); } function drawArc(ctx, element, offset, spacing, circular) { const { fullCircles, startAngle, circumference } = element; let endAngle = element.endAngle; if (fullCircles) { pathArc(ctx, element, offset, spacing, endAngle, circular); for (let i2 = 0; i2 < fullCircles; ++i2) { ctx.fill(); } if (!isNaN(circumference)) { endAngle = startAngle + (circumference % TAU || TAU); } } pathArc(ctx, element, offset, spacing, endAngle, circular); ctx.fill(); return endAngle; } function drawBorder(ctx, element, offset, spacing, circular) { const { fullCircles, startAngle, circumference, options } = element; const { borderWidth, borderJoinStyle, borderDash, borderDashOffset } = options; const inner = options.borderAlign === "inner"; if (!borderWidth) { return; } ctx.setLineDash(borderDash || []); ctx.lineDashOffset = borderDashOffset; if (inner) { ctx.lineWidth = borderWidth * 2; ctx.lineJoin = borderJoinStyle || "round"; } else { ctx.lineWidth = borderWidth; ctx.lineJoin = borderJoinStyle || "bevel"; } let endAngle = element.endAngle; if (fullCircles) { pathArc(ctx, element, offset, spacing, endAngle, circular); for (let i2 = 0; i2 < fullCircles; ++i2) { ctx.stroke(); } if (!isNaN(circumference)) { endAngle = startAngle + (circumference % TAU || TAU); } } if (inner) { clipArc(ctx, element, endAngle); } if (!fullCircles) { pathArc(ctx, element, offset, spacing, endAngle, circular); ctx.stroke(); } } var ArcElement = class extends Element { constructor(cfg) { super(); __publicField(this, "circumference"); __publicField(this, "endAngle"); __publicField(this, "fullCircles"); __publicField(this, "innerRadius"); __publicField(this, "outerRadius"); __publicField(this, "pixelMargin"); __publicField(this, "startAngle"); this.options = void 0; this.circumference = void 0; this.startAngle = void 0; this.endAngle = void 0; this.innerRadius = void 0; this.outerRadius = void 0; this.pixelMargin = 0; this.fullCircles = 0; if (cfg) { Object.assign(this, cfg); } } inRange(chartX, chartY, useFinalPosition) { const point = this.getProps([ "x", "y" ], useFinalPosition); const { angle, distance } = getAngleFromPoint(point, { x: chartX, y: chartY }); const { startAngle, endAngle, innerRadius, outerRadius, circumference } = this.getProps([ "startAngle", "endAngle", "innerRadius", "outerRadius", "circumference" ], useFinalPosition); const rAdjust = (this.options.spacing + this.options.borderWidth) / 2; const _circumference = valueOrDefault(circumference, endAngle - startAngle); const nonZeroBetween = _angleBetween(angle, startAngle, endAngle) && startAngle !== endAngle; const betweenAngles = _circumference >= TAU || nonZeroBetween; const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust); return betweenAngles && withinRadius; } getCenterPoint(useFinalPosition) { const { x: x2, y: y2, startAngle, endAngle, innerRadius, outerRadius } = this.getProps([ "x", "y", "startAngle", "endAngle", "innerRadius", "outerRadius" ], useFinalPosition); const { offset, spacing } = this.options; const halfAngle = (startAngle + endAngle) / 2; const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2; return { x: x2 + Math.cos(halfAngle) * halfRadius, y: y2 + Math.sin(halfAngle) * halfRadius }; } tooltipPosition(useFinalPosition) { return this.getCenterPoint(useFinalPosition); } draw(ctx) { const { options, circumference } = this; const offset = (options.offset || 0) / 4; const spacing = (options.spacing || 0) / 2; const circular = options.circular; this.pixelMargin = options.borderAlign === "inner" ? 0.33 : 0; this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0; if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) { return; } ctx.save(); const halfAngle = (this.startAngle + this.endAngle) / 2; ctx.translate(Math.cos(halfAngle) * offset, Math.sin(halfAngle) * offset); const fix = 1 - Math.sin(Math.min(PI, circumference || 0)); const radiusOffset = offset * fix; ctx.fillStyle = options.backgroundColor; ctx.strokeStyle = options.borderColor; drawArc(ctx, this, radiusOffset, spacing, circular); drawBorder(ctx, this, radiusOffset, spacing, circular); ctx.restore(); } }; __publicField(ArcElement, "id", "arc"); __publicField(ArcElement, "defaults", { borderAlign: "center", borderColor: "#fff", borderDash: [], borderDashOffset: 0, borderJoinStyle: void 0, borderRadius: 0, borderWidth: 2, offset: 0, spacing: 0, angle: void 0, circular: true }); __publicField(ArcElement, "defaultRoutes", { backgroundColor: "backgroundColor" }); __publicField(ArcElement, "descriptors", { _scriptable: true, _indexable: (name) => name !== "borderDash" }); function getBarBounds(bar, useFinalPosition) { const { x: x2, y: y2, base, width, height } = bar.getProps([ "x", "y", "base", "width", "height" ], useFinalPosition); let left, right, top, bottom, half; if (bar.horizontal) { half = height / 2; left = Math.min(x2, base); right = Math.max(x2, base); top = y2 - half; bottom = y2 + half; } else { half = width / 2; left = x2 - half; right = x2 + half; top = Math.min(y2, base); bottom = Math.max(y2, base); } return { left, top, right, bottom }; } function skipOrLimit(skip2, value, min, max) { return skip2 ? 0 : _limitValue(value, min, max); } function parseBorderWidth(bar, maxW, maxH) { const value = bar.options.borderWidth; const skip2 = bar.borderSkipped; const o2 = toTRBL(value); return { t: skipOrLimit(skip2.top, o2.top, 0, maxH), r: skipOrLimit(skip2.right, o2.right, 0, maxW), b: skipOrLimit(skip2.bottom, o2.bottom, 0, maxH), l: skipOrLimit(skip2.left, o2.left, 0, maxW) }; } function parseBorderRadius(bar, maxW, maxH) { const { enableBorderRadius } = bar.getProps([ "enableBorderRadius" ]); const value = bar.options.borderRadius; const o2 = toTRBLCorners(value); const maxR = Math.min(maxW, maxH); const skip2 = bar.borderSkipped; const enableBorder = enableBorderRadius || isObject(value); return { topLeft: skipOrLimit(!enableBorder || skip2.top || skip2.left, o2.topLeft, 0, maxR), topRight: skipOrLimit(!enableBorder || skip2.top || skip2.right, o2.topRight, 0, maxR), bottomLeft: skipOrLimit(!enableBorder || skip2.bottom || skip2.left, o2.bottomLeft, 0, maxR), bottomRight: skipOrLimit(!enableBorder || skip2.bottom || skip2.right, o2.bottomRight, 0, maxR) }; } function boundingRects(bar) { const bounds = getBarBounds(bar); const width = bounds.right - bounds.left; const height = bounds.bottom - bounds.top; const border = parseBorderWidth(bar, width / 2, height / 2); const radius = parseBorderRadius(bar, width / 2, height / 2); return { outer: { x: bounds.left, y: bounds.top, w: width, h: height, radius }, inner: { x: bounds.left + border.l, y: bounds.top + border.t, w: width - border.l - border.r, h: height - border.t - border.b, radius: { topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)), topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)), bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)), bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)) } } }; } function inRange(bar, x2, y2, useFinalPosition) { const skipX = x2 === null; const skipY = y2 === null; const skipBoth = skipX && skipY; const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition); return bounds && (skipX || _isBetween(x2, bounds.left, bounds.right)) && (skipY || _isBetween(y2, bounds.top, bounds.bottom)); } function hasRadius(radius) { return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight; } function addNormalRectPath(ctx, rect) { ctx.rect(rect.x, rect.y, rect.w, rect.h); } function inflateRect(rect, amount, refRect = {}) { const x2 = rect.x !== refRect.x ? -amount : 0; const y2 = rect.y !== refRect.y ? -amount : 0; const w2 = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x2; const h6 = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y2; return { x: rect.x + x2, y: rect.y + y2, w: rect.w + w2, h: rect.h + h6, radius: rect.radius }; } var BarElement = class extends Element { constructor(cfg) { super(); this.options = void 0; this.horizontal = void 0; this.base = void 0; this.width = void 0; this.height = void 0; this.inflateAmount = void 0; if (cfg) { Object.assign(this, cfg); } } draw(ctx) { const { inflateAmount, options: { borderColor, backgroundColor } } = this; const { inner, outer } = boundingRects(this); const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath; ctx.save(); if (outer.w !== inner.w || outer.h !== inner.h) { ctx.beginPath(); addRectPath(ctx, inflateRect(outer, inflateAmount, inner)); ctx.clip(); addRectPath(ctx, inflateRect(inner, -inflateAmount, outer)); ctx.fillStyle = borderColor; ctx.fill("evenodd"); } ctx.beginPath(); addRectPath(ctx, inflateRect(inner, inflateAmount)); ctx.fillStyle = backgroundColor; ctx.fill(); ctx.restore(); } inRange(mouseX, mouseY, useFinalPosition) { return inRange(this, mouseX, mouseY, useFinalPosition); } inXRange(mouseX, useFinalPosition) { return inRange(this, mouseX, null, useFinalPosition); } inYRange(mouseY, useFinalPosition) { return inRange(this, null, mouseY, useFinalPosition); } getCenterPoint(useFinalPosition) { const { x: x2, y: y2, base, horizontal } = this.getProps([ "x", "y", "base", "horizontal" ], useFinalPosition); return { x: horizontal ? (x2 + base) / 2 : x2, y: horizontal ? y2 : (y2 + base) / 2 }; } getRange(axis) { return axis === "x" ? this.width / 2 : this.height / 2; } }; __publicField(BarElement, "id", "bar"); __publicField(BarElement, "defaults", { borderSkipped: "start", borderWidth: 0, borderRadius: 0, inflateAmount: "auto", pointStyle: void 0 }); __publicField(BarElement, "defaultRoutes", { backgroundColor: "backgroundColor", borderColor: "borderColor" }); var getBoxSize = (labelOpts, fontSize) => { let { boxHeight = fontSize, boxWidth = fontSize } = labelOpts; if (labelOpts.usePointStyle) { boxHeight = Math.min(boxHeight, fontSize); boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize); } return { boxWidth, boxHeight, itemHeight: Math.max(fontSize, boxHeight) }; }; var itemsEqual = (a2, b2) => a2 !== null && b2 !== null && a2.datasetIndex === b2.datasetIndex && a2.index === b2.index; var Legend = class extends Element { constructor(config) { super(); this._added = false; this.legendHitBoxes = []; this._hoveredItem = null; this.doughnutMode = false; this.chart = config.chart; this.options = config.options; this.ctx = config.ctx; this.legendItems = void 0; this.columnSizes = void 0; this.lineWidths = void 0; this.maxHeight = void 0; this.maxWidth = void 0; this.top = void 0; this.bottom = void 0; this.left = void 0; this.right = void 0; this.height = void 0; this.width = void 0; this._margins = void 0; this.position = void 0; this.weight = void 0; this.fullSize = void 0; } update(maxWidth, maxHeight, margins) { this.maxWidth = maxWidth; this.maxHeight = maxHeight; this._margins = margins; this.setDimensions(); this.buildLabels(); this.fit(); } setDimensions() { if (this.isHorizontal()) { this.width = this.maxWidth; this.left = this._margins.left; this.right = this.width; } else { this.height = this.maxHeight; this.top = this._margins.top; this.bottom = this.height; } } buildLabels() { const labelOpts = this.options.labels || {}; let legendItems = callback(labelOpts.generateLabels, [ this.chart ], this) || []; if (labelOpts.filter) { legendItems = legendItems.filter((item) => labelOpts.filter(item, this.chart.data)); } if (labelOpts.sort) { legendItems = legendItems.sort((a2, b2) => labelOpts.sort(a2, b2, this.chart.data)); } if (this.options.reverse) { legendItems.reverse(); } this.legendItems = legendItems; } fit() { const { options, ctx } = this; if (!options.display) { this.width = this.height = 0; return; } const labelOpts = options.labels; const labelFont = toFont(labelOpts.font); const fontSize = labelFont.size; const titleHeight = this._computeTitleHeight(); const { boxWidth, itemHeight } = getBoxSize(labelOpts, fontSize); let width, height; ctx.font = labelFont.string; if (this.isHorizontal()) { width = this.maxWidth; height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10; } else { height = this.maxHeight; width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10; } this.width = Math.min(width, options.maxWidth || this.maxWidth); this.height = Math.min(height, options.maxHeight || this.maxHeight); } _fitRows(titleHeight, fontSize, boxWidth, itemHeight) { const { ctx, maxWidth, options: { labels: { padding } } } = this; const hitboxes = this.legendHitBoxes = []; const lineWidths = this.lineWidths = [ 0 ]; const lineHeight = itemHeight + padding; let totalHeight = titleHeight; ctx.textAlign = "left"; ctx.textBaseline = "middle"; let row = -1; let top = -lineHeight; this.legendItems.forEach((legendItem, i2) => { const itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width; if (i2 === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) { totalHeight += lineHeight; lineWidths[lineWidths.length - (i2 > 0 ? 0 : 1)] = 0; top += lineHeight; row++; } hitboxes[i2] = { left: 0, top, row, width: itemWidth, height: itemHeight }; lineWidths[lineWidths.length - 1] += itemWidth + padding; }); return totalHeight; } _fitCols(titleHeight, labelFont, boxWidth, _itemHeight) { const { ctx, maxHeight, options: { labels: { padding } } } = this; const hitboxes = this.legendHitBoxes = []; const columnSizes = this.columnSizes = []; const heightLimit = maxHeight - titleHeight; let totalWidth = padding; let currentColWidth = 0; let currentColHeight = 0; let left = 0; let col = 0; this.legendItems.forEach((legendItem, i2) => { const { itemWidth, itemHeight } = calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight); if (i2 > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) { totalWidth += currentColWidth + padding; columnSizes.push({ width: currentColWidth, height: currentColHeight }); left += currentColWidth + padding; col++; currentColWidth = currentColHeight = 0; } hitboxes[i2] = { left, top: currentColHeight, col, width: itemWidth, height: itemHeight }; currentColWidth = Math.max(currentColWidth, itemWidth); currentColHeight += itemHeight + padding; }); totalWidth += currentColWidth; columnSizes.push({ width: currentColWidth, height: currentColHeight }); return totalWidth; } adjustHitBoxes() { if (!this.options.display) { return; } const titleHeight = this._computeTitleHeight(); const { legendHitBoxes: hitboxes, options: { align, labels: { padding }, rtl } } = this; const rtlHelper = getRtlAdapter(rtl, this.left, this.width); if (this.isHorizontal()) { let row = 0; let left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]); for (const hitbox of hitboxes) { if (row !== hitbox.row) { row = hitbox.row; left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]); } hitbox.top += this.top + titleHeight + padding; hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width); left += hitbox.width + padding; } } else { let col = 0; let top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); for (const hitbox of hitboxes) { if (hitbox.col !== col) { col = hitbox.col; top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); } hitbox.top = top; hitbox.left += this.left + padding; hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width); top += hitbox.height + padding; } } } isHorizontal() { return this.options.position === "top" || this.options.position === "bottom"; } draw() { if (this.options.display) { const ctx = this.ctx; clipArea(ctx, this); this._draw(); unclipArea(ctx); } } _draw() { const { options: opts, columnSizes, lineWidths, ctx } = this; const { align, labels: labelOpts } = opts; const defaultColor = defaults2.color; const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width); const labelFont = toFont(labelOpts.font); const { padding } = labelOpts; const fontSize = labelFont.size; const halfFontSize = fontSize / 2; let cursor; this.drawTitle(); ctx.textAlign = rtlHelper.textAlign("left"); ctx.textBaseline = "middle"; ctx.lineWidth = 0.5; ctx.font = labelFont.string; const { boxWidth, boxHeight, itemHeight } = getBoxSize(labelOpts, fontSize); const drawLegendBox = function(x2, y2, legendItem) { if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) { return; } ctx.save(); const lineWidth = valueOrDefault(legendItem.lineWidth, 1); ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor); ctx.lineCap = valueOrDefault(legendItem.lineCap, "butt"); ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0); ctx.lineJoin = valueOrDefault(legendItem.lineJoin, "miter"); ctx.lineWidth = lineWidth; ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor); ctx.setLineDash(valueOrDefault(legendItem.lineDash, [])); if (labelOpts.usePointStyle) { const drawOptions = { radius: boxHeight * Math.SQRT2 / 2, pointStyle: legendItem.pointStyle, rotation: legendItem.rotation, borderWidth: lineWidth }; const centerX = rtlHelper.xPlus(x2, boxWidth / 2); const centerY = y2 + halfFontSize; drawPointLegend(ctx, drawOptions, centerX, centerY, labelOpts.pointStyleWidth && boxWidth); } else { const yBoxTop = y2 + Math.max((fontSize - boxHeight) / 2, 0); const xBoxLeft = rtlHelper.leftForLtr(x2, boxWidth); const borderRadius = toTRBLCorners(legendItem.borderRadius); ctx.beginPath(); if (Object.values(borderRadius).some((v2) => v2 !== 0)) { addRoundedRectPath(ctx, { x: xBoxLeft, y: yBoxTop, w: boxWidth, h: boxHeight, radius: borderRadius }); } else { ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight); } ctx.fill(); if (lineWidth !== 0) { ctx.stroke(); } } ctx.restore(); }; const fillText = function(x2, y2, legendItem) { renderText(ctx, legendItem.text, x2, y2 + itemHeight / 2, labelFont, { strikethrough: legendItem.hidden, textAlign: rtlHelper.textAlign(legendItem.textAlign) }); }; const isHorizontal = this.isHorizontal(); const titleHeight = this._computeTitleHeight(); if (isHorizontal) { cursor = { x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]), y: this.top + padding + titleHeight, line: 0 }; } else { cursor = { x: this.left + padding, y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height), line: 0 }; } overrideTextDirection(this.ctx, opts.textDirection); const lineHeight = itemHeight + padding; this.legendItems.forEach((legendItem, i2) => { ctx.strokeStyle = legendItem.fontColor; ctx.fillStyle = legendItem.fontColor; const textWidth = ctx.measureText(legendItem.text).width; const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign)); const width = boxWidth + halfFontSize + textWidth; let x2 = cursor.x; let y2 = cursor.y; rtlHelper.setWidth(this.width); if (isHorizontal) { if (i2 > 0 && x2 + width + padding > this.right) { y2 = cursor.y += lineHeight; cursor.line++; x2 = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]); } } else if (i2 > 0 && y2 + lineHeight > this.bottom) { x2 = cursor.x = x2 + columnSizes[cursor.line].width + padding; cursor.line++; y2 = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height); } const realX = rtlHelper.x(x2); drawLegendBox(realX, y2, legendItem); x2 = _textX(textAlign, x2 + boxWidth + halfFontSize, isHorizontal ? x2 + width : this.right, opts.rtl); fillText(rtlHelper.x(x2), y2, legendItem); if (isHorizontal) { cursor.x += width + padding; } else if (typeof legendItem.text !== "string") { const fontLineHeight = labelFont.lineHeight; cursor.y += calculateLegendItemHeight(legendItem, fontLineHeight) + padding; } else { cursor.y += lineHeight; } }); restoreTextDirection(this.ctx, opts.textDirection); } drawTitle() { const opts = this.options; const titleOpts = opts.title; const titleFont = toFont(titleOpts.font); const titlePadding = toPadding(titleOpts.padding); if (!titleOpts.display) { return; } const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width); const ctx = this.ctx; const position = titleOpts.position; const halfFontSize = titleFont.size / 2; const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize; let y2; let left = this.left; let maxWidth = this.width; if (this.isHorizontal()) { maxWidth = Math.max(...this.lineWidths); y2 = this.top + topPaddingPlusHalfFontSize; left = _alignStartEnd(opts.align, left, this.right - maxWidth); } else { const maxHeight = this.columnSizes.reduce((acc, size) => Math.max(acc, size.height), 0); y2 = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight()); } const x2 = _alignStartEnd(position, left, left + maxWidth); ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position)); ctx.textBaseline = "middle"; ctx.strokeStyle = titleOpts.color; ctx.fillStyle = titleOpts.color; ctx.font = titleFont.string; renderText(ctx, titleOpts.text, x2, y2, titleFont); } _computeTitleHeight() { const titleOpts = this.options.title; const titleFont = toFont(titleOpts.font); const titlePadding = toPadding(titleOpts.padding); return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0; } _getLegendItemAt(x2, y2) { let i2, hitBox, lh; if (_isBetween(x2, this.left, this.right) && _isBetween(y2, this.top, this.bottom)) { lh = this.legendHitBoxes; for (i2 = 0; i2 < lh.length; ++i2) { hitBox = lh[i2]; if (_isBetween(x2, hitBox.left, hitBox.left + hitBox.width) && _isBetween(y2, hitBox.top, hitBox.top + hitBox.height)) { return this.legendItems[i2]; } } } return null; } handleEvent(e2) { const opts = this.options; if (!isListened(e2.type, opts)) { return; } const hoveredItem = this._getLegendItemAt(e2.x, e2.y); if (e2.type === "mousemove" || e2.type === "mouseout") { const previous = this._hoveredItem; const sameItem = itemsEqual(previous, hoveredItem); if (previous && !sameItem) { callback(opts.onLeave, [ e2, previous, this ], this); } this._hoveredItem = hoveredItem; if (hoveredItem && !sameItem) { callback(opts.onHover, [ e2, hoveredItem, this ], this); } } else if (hoveredItem) { callback(opts.onClick, [ e2, hoveredItem, this ], this); } } }; function calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight) { const itemWidth = calculateItemWidth(legendItem, boxWidth, labelFont, ctx); const itemHeight = calculateItemHeight(_itemHeight, legendItem, labelFont.lineHeight); return { itemWidth, itemHeight }; } function calculateItemWidth(legendItem, boxWidth, labelFont, ctx) { let legendItemText = legendItem.text; if (legendItemText && typeof legendItemText !== "string") { legendItemText = legendItemText.reduce((a2, b2) => a2.length > b2.length ? a2 : b2); } return boxWidth + labelFont.size / 2 + ctx.measureText(legendItemText).width; } function calculateItemHeight(_itemHeight, legendItem, fontLineHeight) { let itemHeight = _itemHeight; if (typeof legendItem.text !== "string") { itemHeight = calculateLegendItemHeight(legendItem, fontLineHeight); } return itemHeight; } function calculateLegendItemHeight(legendItem, fontLineHeight) { const labelHeight = legendItem.text ? legendItem.text.length : 0; return fontLineHeight * labelHeight; } function isListened(type, opts) { if ((type === "mousemove" || type === "mouseout") && (opts.onHover || opts.onLeave)) { return true; } if (opts.onClick && (type === "click" || type === "mouseup")) { return true; } return false; } var plugin_legend = { id: "legend", _element: Legend, start(chart, _args, options) { const legend = chart.legend = new Legend({ ctx: chart.ctx, options, chart }); layouts.configure(chart, legend, options); layouts.addBox(chart, legend); }, stop(chart) { layouts.removeBox(chart, chart.legend); delete chart.legend; }, beforeUpdate(chart, _args, options) { const legend = chart.legend; layouts.configure(chart, legend, options); legend.options = options; }, afterUpdate(chart) { const legend = chart.legend; legend.buildLabels(); legend.adjustHitBoxes(); }, afterEvent(chart, args) { if (!args.replay) { chart.legend.handleEvent(args.event); } }, defaults: { display: true, position: "top", align: "center", fullSize: true, reverse: false, weight: 1e3, onClick(e2, legendItem, legend) { const index = legendItem.datasetIndex; const ci = legend.chart; if (ci.isDatasetVisible(index)) { ci.hide(index); legendItem.hidden = true; } else { ci.show(index); legendItem.hidden = false; } }, onHover: null, onLeave: null, labels: { color: (ctx) => ctx.chart.options.color, boxWidth: 40, padding: 10, generateLabels(chart) { const datasets = chart.data.datasets; const { labels: { usePointStyle, pointStyle, textAlign, color: color2, useBorderRadius, borderRadius } } = chart.legend.options; return chart._getSortedDatasetMetas().map((meta) => { const style = meta.controller.getStyle(usePointStyle ? 0 : void 0); const borderWidth = toPadding(style.borderWidth); return { text: datasets[meta.index].label, fillStyle: style.backgroundColor, fontColor: color2, hidden: !meta.visible, lineCap: style.borderCapStyle, lineDash: style.borderDash, lineDashOffset: style.borderDashOffset, lineJoin: style.borderJoinStyle, lineWidth: (borderWidth.width + borderWidth.height) / 4, strokeStyle: style.borderColor, pointStyle: pointStyle || style.pointStyle, rotation: style.rotation, textAlign: textAlign || style.textAlign, borderRadius: useBorderRadius && (borderRadius || style.borderRadius), datasetIndex: meta.index }; }, this); } }, title: { color: (ctx) => ctx.chart.options.color, display: false, position: "center", text: "" } }, descriptors: { _scriptable: (name) => !name.startsWith("on"), labels: { _scriptable: (name) => ![ "generateLabels", "filter", "sort" ].includes(name) } } }; var Title = class extends Element { constructor(config) { super(); this.chart = config.chart; this.options = config.options; this.ctx = config.ctx; this._padding = void 0; this.top = void 0; this.bottom = void 0; this.left = void 0; this.right = void 0; this.width = void 0; this.height = void 0; this.position = void 0; this.weight = void 0; this.fullSize = void 0; } update(maxWidth, maxHeight) { const opts = this.options; this.left = 0; this.top = 0; if (!opts.display) { this.width = this.height = this.right = this.bottom = 0; return; } this.width = this.right = maxWidth; this.height = this.bottom = maxHeight; const lineCount = isArray(opts.text) ? opts.text.length : 1; this._padding = toPadding(opts.padding); const textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height; if (this.isHorizontal()) { this.height = textSize; } else { this.width = textSize; } } isHorizontal() { const pos = this.options.position; return pos === "top" || pos === "bottom"; } _drawArgs(offset) { const { top, left, bottom, right, options } = this; const align = options.align; let rotation = 0; let maxWidth, titleX, titleY; if (this.isHorizontal()) { titleX = _alignStartEnd(align, left, right); titleY = top + offset; maxWidth = right - left; } else { if (options.position === "left") { titleX = left + offset; titleY = _alignStartEnd(align, bottom, top); rotation = PI * -0.5; } else { titleX = right - offset; titleY = _alignStartEnd(align, top, bottom); rotation = PI * 0.5; } maxWidth = bottom - top; } return { titleX, titleY, maxWidth, rotation }; } draw() { const ctx = this.ctx; const opts = this.options; if (!opts.display) { return; } const fontOpts = toFont(opts.font); const lineHeight = fontOpts.lineHeight; const offset = lineHeight / 2 + this._padding.top; const { titleX, titleY, maxWidth, rotation } = this._drawArgs(offset); renderText(ctx, opts.text, 0, 0, fontOpts, { color: opts.color, maxWidth, rotation, textAlign: _toLeftRightCenter(opts.align), textBaseline: "middle", translation: [ titleX, titleY ] }); } }; function createTitle(chart, titleOpts) { const title = new Title({ ctx: chart.ctx, options: titleOpts, chart }); layouts.configure(chart, title, titleOpts); layouts.addBox(chart, title); chart.titleBlock = title; } var plugin_title = { id: "title", _element: Title, start(chart, _args, options) { createTitle(chart, options); }, stop(chart) { const titleBlock = chart.titleBlock; layouts.removeBox(chart, titleBlock); delete chart.titleBlock; }, beforeUpdate(chart, _args, options) { const title = chart.titleBlock; layouts.configure(chart, title, options); title.options = options; }, defaults: { align: "center", display: false, font: { weight: "bold" }, fullSize: true, padding: 10, position: "top", text: "", weight: 2e3 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: true, _indexable: false } }; var map2 = /* @__PURE__ */ new WeakMap(); var plugin_subtitle = { id: "subtitle", start(chart, _args, options) { const title = new Title({ ctx: chart.ctx, options, chart }); layouts.configure(chart, title, options); layouts.addBox(chart, title); map2.set(chart, title); }, stop(chart) { layouts.removeBox(chart, map2.get(chart)); map2.delete(chart); }, beforeUpdate(chart, _args, options) { const title = map2.get(chart); layouts.configure(chart, title, options); title.options = options; }, defaults: { align: "center", display: false, font: { weight: "normal" }, fullSize: true, padding: 0, position: "top", text: "", weight: 1500 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: true, _indexable: false } }; var positioners = { average(items) { if (!items.length) { return false; } let i2, len; let xSet = /* @__PURE__ */ new Set(); let y2 = 0; let count = 0; for (i2 = 0, len = items.length; i2 < len; ++i2) { const el = items[i2].element; if (el && el.hasValue()) { const pos = el.tooltipPosition(); xSet.add(pos.x); y2 += pos.y; ++count; } } if (count === 0 || xSet.size === 0) { return false; } const xAverage = [ ...xSet ].reduce((a2, b2) => a2 + b2) / xSet.size; return { x: xAverage, y: y2 / count }; }, nearest(items, eventPosition) { if (!items.length) { return false; } let x2 = eventPosition.x; let y2 = eventPosition.y; let minDistance = Number.POSITIVE_INFINITY; let i2, len, nearestElement; for (i2 = 0, len = items.length; i2 < len; ++i2) { const el = items[i2].element; if (el && el.hasValue()) { const center = el.getCenterPoint(); const d2 = distanceBetweenPoints(eventPosition, center); if (d2 < minDistance) { minDistance = d2; nearestElement = el; } } } if (nearestElement) { const tp = nearestElement.tooltipPosition(); x2 = tp.x; y2 = tp.y; } return { x: x2, y: y2 }; } }; function pushOrConcat(base, toPush) { if (toPush) { if (isArray(toPush)) { Array.prototype.push.apply(base, toPush); } else { base.push(toPush); } } return base; } function splitNewlines(str) { if ((typeof str === "string" || str instanceof String) && str.indexOf("\n") > -1) { return str.split("\n"); } return str; } function createTooltipItem(chart, item) { const { element, datasetIndex, index } = item; const controller = chart.getDatasetMeta(datasetIndex).controller; const { label, value } = controller.getLabelAndValue(index); return { chart, label, parsed: controller.getParsed(index), raw: chart.data.datasets[datasetIndex].data[index], formattedValue: value, dataset: controller.getDataset(), dataIndex: index, datasetIndex, element }; } function getTooltipSize(tooltip, options) { const ctx = tooltip.chart.ctx; const { body, footer, title } = tooltip; const { boxWidth, boxHeight } = options; const bodyFont = toFont(options.bodyFont); const titleFont = toFont(options.titleFont); const footerFont = toFont(options.footerFont); const titleLineCount = title.length; const footerLineCount = footer.length; const bodyLineItemCount = body.length; const padding = toPadding(options.padding); let height = padding.height; let width = 0; let combinedBodyLength = body.reduce((count, bodyItem) => count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0); combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length; if (titleLineCount) { height += titleLineCount * titleFont.lineHeight + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom; } if (combinedBodyLength) { const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight; height += bodyLineItemCount * bodyLineHeight + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight + (combinedBodyLength - 1) * options.bodySpacing; } if (footerLineCount) { height += options.footerMarginTop + footerLineCount * footerFont.lineHeight + (footerLineCount - 1) * options.footerSpacing; } let widthPadding = 0; const maxLineWidth = function(line) { width = Math.max(width, ctx.measureText(line).width + widthPadding); }; ctx.save(); ctx.font = titleFont.string; each(tooltip.title, maxLineWidth); ctx.font = bodyFont.string; each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth); widthPadding = options.displayColors ? boxWidth + 2 + options.boxPadding : 0; each(body, (bodyItem) => { each(bodyItem.before, maxLineWidth); each(bodyItem.lines, maxLineWidth); each(bodyItem.after, maxLineWidth); }); widthPadding = 0; ctx.font = footerFont.string; each(tooltip.footer, maxLineWidth); ctx.restore(); width += padding.width; return { width, height }; } function determineYAlign(chart, size) { const { y: y2, height } = size; if (y2 < height / 2) { return "top"; } else if (y2 > chart.height - height / 2) { return "bottom"; } return "center"; } function doesNotFitWithAlign(xAlign, chart, options, size) { const { x: x2, width } = size; const caret = options.caretSize + options.caretPadding; if (xAlign === "left" && x2 + width + caret > chart.width) { return true; } if (xAlign === "right" && x2 - width - caret < 0) { return true; } } function determineXAlign(chart, options, size, yAlign) { const { x: x2, width } = size; const { width: chartWidth, chartArea: { left, right } } = chart; let xAlign = "center"; if (yAlign === "center") { xAlign = x2 <= (left + right) / 2 ? "left" : "right"; } else if (x2 <= width / 2) { xAlign = "left"; } else if (x2 >= chartWidth - width / 2) { xAlign = "right"; } if (doesNotFitWithAlign(xAlign, chart, options, size)) { xAlign = "center"; } return xAlign; } function determineAlignment(chart, options, size) { const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size); return { xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign), yAlign }; } function alignX(size, xAlign) { let { x: x2, width } = size; if (xAlign === "right") { x2 -= width; } else if (xAlign === "center") { x2 -= width / 2; } return x2; } function alignY(size, yAlign, paddingAndSize) { let { y: y2, height } = size; if (yAlign === "top") { y2 += paddingAndSize; } else if (yAlign === "bottom") { y2 -= height + paddingAndSize; } else { y2 -= height / 2; } return y2; } function getBackgroundPoint(options, size, alignment, chart) { const { caretSize, caretPadding, cornerRadius } = options; const { xAlign, yAlign } = alignment; const paddingAndSize = caretSize + caretPadding; const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(cornerRadius); let x2 = alignX(size, xAlign); const y2 = alignY(size, yAlign, paddingAndSize); if (yAlign === "center") { if (xAlign === "left") { x2 += paddingAndSize; } else if (xAlign === "right") { x2 -= paddingAndSize; } } else if (xAlign === "left") { x2 -= Math.max(topLeft, bottomLeft) + caretSize; } else if (xAlign === "right") { x2 += Math.max(topRight, bottomRight) + caretSize; } return { x: _limitValue(x2, 0, chart.width - size.width), y: _limitValue(y2, 0, chart.height - size.height) }; } function getAlignedX(tooltip, align, options) { const padding = toPadding(options.padding); return align === "center" ? tooltip.x + tooltip.width / 2 : align === "right" ? tooltip.x + tooltip.width - padding.right : tooltip.x + padding.left; } function getBeforeAfterBodyLines(callback2) { return pushOrConcat([], splitNewlines(callback2)); } function createTooltipContext(parent, tooltip, tooltipItems) { return createContext(parent, { tooltip, tooltipItems, type: "tooltip" }); } function overrideCallbacks(callbacks, context) { const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks; return override ? callbacks.override(override) : callbacks; } var defaultCallbacks = { beforeTitle: noop, title(tooltipItems) { if (tooltipItems.length > 0) { const item = tooltipItems[0]; const labels = item.chart.data.labels; const labelCount = labels ? labels.length : 0; if (this && this.options && this.options.mode === "dataset") { return item.dataset.label || ""; } else if (item.label) { return item.label; } else if (labelCount > 0 && item.dataIndex < labelCount) { return labels[item.dataIndex]; } } return ""; }, afterTitle: noop, beforeBody: noop, beforeLabel: noop, label(tooltipItem) { if (this && this.options && this.options.mode === "dataset") { return tooltipItem.label + ": " + tooltipItem.formattedValue || tooltipItem.formattedValue; } let label = tooltipItem.dataset.label || ""; if (label) { label += ": "; } const value = tooltipItem.formattedValue; if (!isNullOrUndef(value)) { label += value; } return label; }, labelColor(tooltipItem) { const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); const options = meta.controller.getStyle(tooltipItem.dataIndex); return { borderColor: options.borderColor, backgroundColor: options.backgroundColor, borderWidth: options.borderWidth, borderDash: options.borderDash, borderDashOffset: options.borderDashOffset, borderRadius: 0 }; }, labelTextColor() { return this.options.bodyColor; }, labelPointStyle(tooltipItem) { const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); const options = meta.controller.getStyle(tooltipItem.dataIndex); return { pointStyle: options.pointStyle, rotation: options.rotation }; }, afterLabel: noop, afterBody: noop, beforeFooter: noop, footer: noop, afterFooter: noop }; function invokeCallbackWithFallback(callbacks, name, ctx, arg) { const result = callbacks[name].call(ctx, arg); if (typeof result === "undefined") { return defaultCallbacks[name].call(ctx, arg); } return result; } var Tooltip = class extends Element { constructor(config) { super(); this.opacity = 0; this._active = []; this._eventPosition = void 0; this._size = void 0; this._cachedAnimations = void 0; this._tooltipItems = []; this.$animations = void 0; this.$context = void 0; this.chart = config.chart; this.options = config.options; this.dataPoints = void 0; this.title = void 0; this.beforeBody = void 0; this.body = void 0; this.afterBody = void 0; this.footer = void 0; this.xAlign = void 0; this.yAlign = void 0; this.x = void 0; this.y = void 0; this.height = void 0; this.width = void 0; this.caretX = void 0; this.caretY = void 0; this.labelColors = void 0; this.labelPointStyles = void 0; this.labelTextColors = void 0; } initialize(options) { this.options = options; this._cachedAnimations = void 0; this.$context = void 0; } _resolveAnimations() { const cached = this._cachedAnimations; if (cached) { return cached; } const chart = this.chart; const options = this.options.setContext(this.getContext()); const opts = options.enabled && chart.options.animation && options.animations; const animations = new Animations(this.chart, opts); if (opts._cacheable) { this._cachedAnimations = Object.freeze(animations); } return animations; } getContext() { return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems)); } getTitle(context, options) { const { callbacks } = options; const beforeTitle = invokeCallbackWithFallback(callbacks, "beforeTitle", this, context); const title = invokeCallbackWithFallback(callbacks, "title", this, context); const afterTitle = invokeCallbackWithFallback(callbacks, "afterTitle", this, context); let lines = []; lines = pushOrConcat(lines, splitNewlines(beforeTitle)); lines = pushOrConcat(lines, splitNewlines(title)); lines = pushOrConcat(lines, splitNewlines(afterTitle)); return lines; } getBeforeBody(tooltipItems, options) { return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, "beforeBody", this, tooltipItems)); } getBody(tooltipItems, options) { const { callbacks } = options; const bodyItems = []; each(tooltipItems, (context) => { const bodyItem = { before: [], lines: [], after: [] }; const scoped = overrideCallbacks(callbacks, context); pushOrConcat(bodyItem.before, splitNewlines(invokeCallbackWithFallback(scoped, "beforeLabel", this, context))); pushOrConcat(bodyItem.lines, invokeCallbackWithFallback(scoped, "label", this, context)); pushOrConcat(bodyItem.after, splitNewlines(invokeCallbackWithFallback(scoped, "afterLabel", this, context))); bodyItems.push(bodyItem); }); return bodyItems; } getAfterBody(tooltipItems, options) { return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, "afterBody", this, tooltipItems)); } getFooter(tooltipItems, options) { const { callbacks } = options; const beforeFooter = invokeCallbackWithFallback(callbacks, "beforeFooter", this, tooltipItems); const footer = invokeCallbackWithFallback(callbacks, "footer", this, tooltipItems); const afterFooter = invokeCallbackWithFallback(callbacks, "afterFooter", this, tooltipItems); let lines = []; lines = pushOrConcat(lines, splitNewlines(beforeFooter)); lines = pushOrConcat(lines, splitNewlines(footer)); lines = pushOrConcat(lines, splitNewlines(afterFooter)); return lines; } _createItems(options) { const active = this._active; const data = this.chart.data; const labelColors = []; const labelPointStyles = []; const labelTextColors = []; let tooltipItems = []; let i2, len; for (i2 = 0, len = active.length; i2 < len; ++i2) { tooltipItems.push(createTooltipItem(this.chart, active[i2])); } if (options.filter) { tooltipItems = tooltipItems.filter((element, index, array) => options.filter(element, index, array, data)); } if (options.itemSort) { tooltipItems = tooltipItems.sort((a2, b2) => options.itemSort(a2, b2, data)); } each(tooltipItems, (context) => { const scoped = overrideCallbacks(options.callbacks, context); labelColors.push(invokeCallbackWithFallback(scoped, "labelColor", this, context)); labelPointStyles.push(invokeCallbackWithFallback(scoped, "labelPointStyle", this, context)); labelTextColors.push(invokeCallbackWithFallback(scoped, "labelTextColor", this, context)); }); this.labelColors = labelColors; this.labelPointStyles = labelPointStyles; this.labelTextColors = labelTextColors; this.dataPoints = tooltipItems; return tooltipItems; } update(changed, replay) { const options = this.options.setContext(this.getContext()); const active = this._active; let properties; let tooltipItems = []; if (!active.length) { if (this.opacity !== 0) { properties = { opacity: 0 }; } } else { const position = positioners[options.position].call(this, active, this._eventPosition); tooltipItems = this._createItems(options); this.title = this.getTitle(tooltipItems, options); this.beforeBody = this.getBeforeBody(tooltipItems, options); this.body = this.getBody(tooltipItems, options); this.afterBody = this.getAfterBody(tooltipItems, options); this.footer = this.getFooter(tooltipItems, options); const size = this._size = getTooltipSize(this, options); const positionAndSize = Object.assign({}, position, size); const alignment = determineAlignment(this.chart, options, positionAndSize); const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart); this.xAlign = alignment.xAlign; this.yAlign = alignment.yAlign; properties = { opacity: 1, x: backgroundPoint.x, y: backgroundPoint.y, width: size.width, height: size.height, caretX: position.x, caretY: position.y }; } this._tooltipItems = tooltipItems; this.$context = void 0; if (properties) { this._resolveAnimations().update(this, properties); } if (changed && options.external) { options.external.call(this, { chart: this.chart, tooltip: this, replay }); } } drawCaret(tooltipPoint, ctx, size, options) { const caretPosition = this.getCaretPosition(tooltipPoint, size, options); ctx.lineTo(caretPosition.x1, caretPosition.y1); ctx.lineTo(caretPosition.x2, caretPosition.y2); ctx.lineTo(caretPosition.x3, caretPosition.y3); } getCaretPosition(tooltipPoint, size, options) { const { xAlign, yAlign } = this; const { caretSize, cornerRadius } = options; const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(cornerRadius); const { x: ptX, y: ptY } = tooltipPoint; const { width, height } = size; let x1, x2, x3, y1, y2, y3; if (yAlign === "center") { y2 = ptY + height / 2; if (xAlign === "left") { x1 = ptX; x2 = x1 - caretSize; y1 = y2 + caretSize; y3 = y2 - caretSize; } else { x1 = ptX + width; x2 = x1 + caretSize; y1 = y2 - caretSize; y3 = y2 + caretSize; } x3 = x1; } else { if (xAlign === "left") { x2 = ptX + Math.max(topLeft, bottomLeft) + caretSize; } else if (xAlign === "right") { x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize; } else { x2 = this.caretX; } if (yAlign === "top") { y1 = ptY; y2 = y1 - caretSize; x1 = x2 - caretSize; x3 = x2 + caretSize; } else { y1 = ptY + height; y2 = y1 + caretSize; x1 = x2 + caretSize; x3 = x2 - caretSize; } y3 = y1; } return { x1, x2, x3, y1, y2, y3 }; } drawTitle(pt2, ctx, options) { const title = this.title; const length = title.length; let titleFont, titleSpacing, i2; if (length) { const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); pt2.x = getAlignedX(this, options.titleAlign, options); ctx.textAlign = rtlHelper.textAlign(options.titleAlign); ctx.textBaseline = "middle"; titleFont = toFont(options.titleFont); titleSpacing = options.titleSpacing; ctx.fillStyle = options.titleColor; ctx.font = titleFont.string; for (i2 = 0; i2 < length; ++i2) { ctx.fillText(title[i2], rtlHelper.x(pt2.x), pt2.y + titleFont.lineHeight / 2); pt2.y += titleFont.lineHeight + titleSpacing; if (i2 + 1 === length) { pt2.y += options.titleMarginBottom - titleSpacing; } } } } _drawColorBox(ctx, pt2, i2, rtlHelper, options) { const labelColor = this.labelColors[i2]; const labelPointStyle = this.labelPointStyles[i2]; const { boxHeight, boxWidth } = options; const bodyFont = toFont(options.bodyFont); const colorX = getAlignedX(this, "left", options); const rtlColorX = rtlHelper.x(colorX); const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0; const colorY = pt2.y + yOffSet; if (options.usePointStyle) { const drawOptions = { radius: Math.min(boxWidth, boxHeight) / 2, pointStyle: labelPointStyle.pointStyle, rotation: labelPointStyle.rotation, borderWidth: 1 }; const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2; const centerY = colorY + boxHeight / 2; ctx.strokeStyle = options.multiKeyBackground; ctx.fillStyle = options.multiKeyBackground; drawPoint(ctx, drawOptions, centerX, centerY); ctx.strokeStyle = labelColor.borderColor; ctx.fillStyle = labelColor.backgroundColor; drawPoint(ctx, drawOptions, centerX, centerY); } else { ctx.lineWidth = isObject(labelColor.borderWidth) ? Math.max(...Object.values(labelColor.borderWidth)) : labelColor.borderWidth || 1; ctx.strokeStyle = labelColor.borderColor; ctx.setLineDash(labelColor.borderDash || []); ctx.lineDashOffset = labelColor.borderDashOffset || 0; const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth); const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2); const borderRadius = toTRBLCorners(labelColor.borderRadius); if (Object.values(borderRadius).some((v2) => v2 !== 0)) { ctx.beginPath(); ctx.fillStyle = options.multiKeyBackground; addRoundedRectPath(ctx, { x: outerX, y: colorY, w: boxWidth, h: boxHeight, radius: borderRadius }); ctx.fill(); ctx.stroke(); ctx.fillStyle = labelColor.backgroundColor; ctx.beginPath(); addRoundedRectPath(ctx, { x: innerX, y: colorY + 1, w: boxWidth - 2, h: boxHeight - 2, radius: borderRadius }); ctx.fill(); } else { ctx.fillStyle = options.multiKeyBackground; ctx.fillRect(outerX, colorY, boxWidth, boxHeight); ctx.strokeRect(outerX, colorY, boxWidth, boxHeight); ctx.fillStyle = labelColor.backgroundColor; ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2); } } ctx.fillStyle = this.labelTextColors[i2]; } drawBody(pt2, ctx, options) { const { body } = this; const { bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth, boxPadding } = options; const bodyFont = toFont(options.bodyFont); let bodyLineHeight = bodyFont.lineHeight; let xLinePadding = 0; const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); const fillLineOfText = function(line) { ctx.fillText(line, rtlHelper.x(pt2.x + xLinePadding), pt2.y + bodyLineHeight / 2); pt2.y += bodyLineHeight + bodySpacing; }; const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign); let bodyItem, textColor, lines, i2, j2, ilen, jlen; ctx.textAlign = bodyAlign; ctx.textBaseline = "middle"; ctx.font = bodyFont.string; pt2.x = getAlignedX(this, bodyAlignForCalculation, options); ctx.fillStyle = options.bodyColor; each(this.beforeBody, fillLineOfText); xLinePadding = displayColors && bodyAlignForCalculation !== "right" ? bodyAlign === "center" ? boxWidth / 2 + boxPadding : boxWidth + 2 + boxPadding : 0; for (i2 = 0, ilen = body.length; i2 < ilen; ++i2) { bodyItem = body[i2]; textColor = this.labelTextColors[i2]; ctx.fillStyle = textColor; each(bodyItem.before, fillLineOfText); lines = bodyItem.lines; if (displayColors && lines.length) { this._drawColorBox(ctx, pt2, i2, rtlHelper, options); bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight); } for (j2 = 0, jlen = lines.length; j2 < jlen; ++j2) { fillLineOfText(lines[j2]); bodyLineHeight = bodyFont.lineHeight; } each(bodyItem.after, fillLineOfText); } xLinePadding = 0; bodyLineHeight = bodyFont.lineHeight; each(this.afterBody, fillLineOfText); pt2.y -= bodySpacing; } drawFooter(pt2, ctx, options) { const footer = this.footer; const length = footer.length; let footerFont, i2; if (length) { const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); pt2.x = getAlignedX(this, options.footerAlign, options); pt2.y += options.footerMarginTop; ctx.textAlign = rtlHelper.textAlign(options.footerAlign); ctx.textBaseline = "middle"; footerFont = toFont(options.footerFont); ctx.fillStyle = options.footerColor; ctx.font = footerFont.string; for (i2 = 0; i2 < length; ++i2) { ctx.fillText(footer[i2], rtlHelper.x(pt2.x), pt2.y + footerFont.lineHeight / 2); pt2.y += footerFont.lineHeight + options.footerSpacing; } } } drawBackground(pt2, ctx, tooltipSize, options) { const { xAlign, yAlign } = this; const { x: x2, y: y2 } = pt2; const { width, height } = tooltipSize; const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(options.cornerRadius); ctx.fillStyle = options.backgroundColor; ctx.strokeStyle = options.borderColor; ctx.lineWidth = options.borderWidth; ctx.beginPath(); ctx.moveTo(x2 + topLeft, y2); if (yAlign === "top") { this.drawCaret(pt2, ctx, tooltipSize, options); } ctx.lineTo(x2 + width - topRight, y2); ctx.quadraticCurveTo(x2 + width, y2, x2 + width, y2 + topRight); if (yAlign === "center" && xAlign === "right") { this.drawCaret(pt2, ctx, tooltipSize, options); } ctx.lineTo(x2 + width, y2 + height - bottomRight); ctx.quadraticCurveTo(x2 + width, y2 + height, x2 + width - bottomRight, y2 + height); if (yAlign === "bottom") { this.drawCaret(pt2, ctx, tooltipSize, options); } ctx.lineTo(x2 + bottomLeft, y2 + height); ctx.quadraticCurveTo(x2, y2 + height, x2, y2 + height - bottomLeft); if (yAlign === "center" && xAlign === "left") { this.drawCaret(pt2, ctx, tooltipSize, options); } ctx.lineTo(x2, y2 + topLeft); ctx.quadraticCurveTo(x2, y2, x2 + topLeft, y2); ctx.closePath(); ctx.fill(); if (options.borderWidth > 0) { ctx.stroke(); } } _updateAnimationTarget(options) { const chart = this.chart; const anims = this.$animations; const animX = anims && anims.x; const animY = anims && anims.y; if (animX || animY) { const position = positioners[options.position].call(this, this._active, this._eventPosition); if (!position) { return; } const size = this._size = getTooltipSize(this, options); const positionAndSize = Object.assign({}, position, this._size); const alignment = determineAlignment(chart, options, positionAndSize); const point = getBackgroundPoint(options, positionAndSize, alignment, chart); if (animX._to !== point.x || animY._to !== point.y) { this.xAlign = alignment.xAlign; this.yAlign = alignment.yAlign; this.width = size.width; this.height = size.height; this.caretX = position.x; this.caretY = position.y; this._resolveAnimations().update(this, point); } } } _willRender() { return !!this.opacity; } draw(ctx) { const options = this.options.setContext(this.getContext()); let opacity = this.opacity; if (!opacity) { return; } this._updateAnimationTarget(options); const tooltipSize = { width: this.width, height: this.height }; const pt2 = { x: this.x, y: this.y }; opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity; const padding = toPadding(options.padding); const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length; if (options.enabled && hasTooltipContent) { ctx.save(); ctx.globalAlpha = opacity; this.drawBackground(pt2, ctx, tooltipSize, options); overrideTextDirection(ctx, options.textDirection); pt2.y += padding.top; this.drawTitle(pt2, ctx, options); this.drawBody(pt2, ctx, options); this.drawFooter(pt2, ctx, options); restoreTextDirection(ctx, options.textDirection); ctx.restore(); } } getActiveElements() { return this._active || []; } setActiveElements(activeElements, eventPosition) { const lastActive = this._active; const active = activeElements.map(({ datasetIndex, index }) => { const meta = this.chart.getDatasetMeta(datasetIndex); if (!meta) { throw new Error("Cannot find a dataset at index " + datasetIndex); } return { datasetIndex, element: meta.data[index], index }; }); const changed = !_elementsEqual(lastActive, active); const positionChanged = this._positionChanged(active, eventPosition); if (changed || positionChanged) { this._active = active; this._eventPosition = eventPosition; this._ignoreReplayEvents = true; this.update(true); } } handleEvent(e2, replay, inChartArea = true) { if (replay && this._ignoreReplayEvents) { return false; } this._ignoreReplayEvents = false; const options = this.options; const lastActive = this._active || []; const active = this._getActiveElements(e2, lastActive, replay, inChartArea); const positionChanged = this._positionChanged(active, e2); const changed = replay || !_elementsEqual(active, lastActive) || positionChanged; if (changed) { this._active = active; if (options.enabled || options.external) { this._eventPosition = { x: e2.x, y: e2.y }; this.update(true, replay); } } return changed; } _getActiveElements(e2, lastActive, replay, inChartArea) { const options = this.options; if (e2.type === "mouseout") { return []; } if (!inChartArea) { return lastActive.filter((i2) => this.chart.data.datasets[i2.datasetIndex] && this.chart.getDatasetMeta(i2.datasetIndex).controller.getParsed(i2.index) !== void 0); } const active = this.chart.getElementsAtEventForMode(e2, options.mode, options, replay); if (options.reverse) { active.reverse(); } return active; } _positionChanged(active, e2) { const { caretX, caretY, options } = this; const position = positioners[options.position].call(this, active, e2); return position !== false && (caretX !== position.x || caretY !== position.y); } }; __publicField(Tooltip, "positioners", positioners); var plugin_tooltip = { id: "tooltip", _element: Tooltip, positioners, afterInit(chart, _args, options) { if (options) { chart.tooltip = new Tooltip({ chart, options }); } }, beforeUpdate(chart, _args, options) { if (chart.tooltip) { chart.tooltip.initialize(options); } }, reset(chart, _args, options) { if (chart.tooltip) { chart.tooltip.initialize(options); } }, afterDraw(chart) { const tooltip = chart.tooltip; if (tooltip && tooltip._willRender()) { const args = { tooltip }; if (chart.notifyPlugins("beforeTooltipDraw", { ...args, cancelable: true }) === false) { return; } tooltip.draw(chart.ctx); chart.notifyPlugins("afterTooltipDraw", args); } }, afterEvent(chart, args) { if (chart.tooltip) { const useFinalPosition = args.replay; if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) { args.changed = true; } } }, defaults: { enabled: true, external: null, position: "average", backgroundColor: "rgba(0,0,0,0.8)", titleColor: "#fff", titleFont: { weight: "bold" }, titleSpacing: 2, titleMarginBottom: 6, titleAlign: "left", bodyColor: "#fff", bodySpacing: 2, bodyFont: {}, bodyAlign: "left", footerColor: "#fff", footerSpacing: 2, footerMarginTop: 6, footerFont: { weight: "bold" }, footerAlign: "left", padding: 6, caretPadding: 2, caretSize: 5, cornerRadius: 6, boxHeight: (ctx, opts) => opts.bodyFont.size, boxWidth: (ctx, opts) => opts.bodyFont.size, multiKeyBackground: "#fff", displayColors: true, boxPadding: 0, borderColor: "rgba(0,0,0,0)", borderWidth: 0, animation: { duration: 400, easing: "easeOutQuart" }, animations: { numbers: { type: "number", properties: [ "x", "y", "width", "height", "caretX", "caretY" ] }, opacity: { easing: "linear", duration: 200 } }, callbacks: defaultCallbacks }, defaultRoutes: { bodyFont: "font", footerFont: "font", titleFont: "font" }, descriptors: { _scriptable: (name) => name !== "filter" && name !== "itemSort" && name !== "external", _indexable: false, callbacks: { _scriptable: false, _indexable: false }, animation: { _fallback: false }, animations: { _fallback: "animation" } }, additionalOptionScopes: [ "interaction" ] }; var addIfString = (labels, raw, index, addedLabels) => { if (typeof raw === "string") { index = labels.push(raw) - 1; addedLabels.unshift({ index, label: raw }); } else if (isNaN(raw)) { index = null; } return index; }; function findOrAddLabel(labels, raw, index, addedLabels) { const first = labels.indexOf(raw); if (first === -1) { return addIfString(labels, raw, index, addedLabels); } const last = labels.lastIndexOf(raw); return first !== last ? index : first; } var validIndex = (index, max) => index === null ? null : _limitValue(Math.round(index), 0, max); function _getLabelForValue(value) { const labels = this.getLabels(); if (value >= 0 && value < labels.length) { return labels[value]; } return value; } var CategoryScale = class extends Scale { constructor(cfg) { super(cfg); this._startValue = void 0; this._valueRange = 0; this._addedLabels = []; } init(scaleOptions) { const added = this._addedLabels; if (added.length) { const labels = this.getLabels(); for (const { index, label } of added) { if (labels[index] === label) { labels.splice(index, 1); } } this._addedLabels = []; } super.init(scaleOptions); } parse(raw, index) { if (isNullOrUndef(raw)) { return null; } const labels = this.getLabels(); index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels); return validIndex(index, labels.length - 1); } determineDataLimits() { const { minDefined, maxDefined } = this.getUserBounds(); let { min, max } = this.getMinMax(true); if (this.options.bounds === "ticks") { if (!minDefined) { min = 0; } if (!maxDefined) { max = this.getLabels().length - 1; } } this.min = min; this.max = max; } buildTicks() { const min = this.min; const max = this.max; const offset = this.options.offset; const ticks = []; let labels = this.getLabels(); labels = min === 0 && max === labels.length - 1 ? labels : labels.slice(min, max + 1); this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1); this._startValue = this.min - (offset ? 0.5 : 0); for (let value = min; value <= max; value++) { ticks.push({ value }); } return ticks; } getLabelForValue(value) { return _getLabelForValue.call(this, value); } configure() { super.configure(); if (!this.isHorizontal()) { this._reversePixels = !this._reversePixels; } } getPixelForValue(value) { if (typeof value !== "number") { value = this.parse(value); } return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); } getPixelForTick(index) { const ticks = this.ticks; if (index < 0 || index > ticks.length - 1) { return null; } return this.getPixelForValue(ticks[index].value); } getValueForPixel(pixel) { return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange); } getBasePixel() { return this.bottom; } }; __publicField(CategoryScale, "id", "category"); __publicField(CategoryScale, "defaults", { ticks: { callback: _getLabelForValue } }); function generateTicks$1(generationOptions, dataRange) { const ticks = []; const MIN_SPACING = 1e-14; const { bounds, step, min, max, precision, count, maxTicks, maxDigits, includeBounds } = generationOptions; const unit = step || 1; const maxSpaces = maxTicks - 1; const { min: rmin, max: rmax } = dataRange; const minDefined = !isNullOrUndef(min); const maxDefined = !isNullOrUndef(max); const countDefined = !isNullOrUndef(count); const minSpacing = (rmax - rmin) / (maxDigits + 1); let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit; let factor, niceMin, niceMax, numSpaces; if (spacing < MIN_SPACING && !minDefined && !maxDefined) { return [ { value: rmin }, { value: rmax } ]; } numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing); if (numSpaces > maxSpaces) { spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit; } if (!isNullOrUndef(precision)) { factor = Math.pow(10, precision); spacing = Math.ceil(spacing * factor) / factor; } if (bounds === "ticks") { niceMin = Math.floor(rmin / spacing) * spacing; niceMax = Math.ceil(rmax / spacing) * spacing; } else { niceMin = rmin; niceMax = rmax; } if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1e3)) { numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks)); spacing = (max - min) / numSpaces; niceMin = min; niceMax = max; } else if (countDefined) { niceMin = minDefined ? min : niceMin; niceMax = maxDefined ? max : niceMax; numSpaces = count - 1; spacing = (niceMax - niceMin) / numSpaces; } else { numSpaces = (niceMax - niceMin) / spacing; if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1e3)) { numSpaces = Math.round(numSpaces); } else { numSpaces = Math.ceil(numSpaces); } } const decimalPlaces = Math.max(_decimalPlaces(spacing), _decimalPlaces(niceMin)); factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision); niceMin = Math.round(niceMin * factor) / factor; niceMax = Math.round(niceMax * factor) / factor; let j2 = 0; if (minDefined) { if (includeBounds && niceMin !== min) { ticks.push({ value: min }); if (niceMin < min) { j2++; } if (almostEquals(Math.round((niceMin + j2 * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) { j2++; } } else if (niceMin < min) { j2++; } } for (; j2 < numSpaces; ++j2) { const tickValue = Math.round((niceMin + j2 * spacing) * factor) / factor; if (maxDefined && tickValue > max) { break; } ticks.push({ value: tickValue }); } if (maxDefined && includeBounds && niceMax !== max) { if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) { ticks[ticks.length - 1].value = max; } else { ticks.push({ value: max }); } } else if (!maxDefined || niceMax === max) { ticks.push({ value: niceMax }); } return ticks; } function relativeLabelSize(value, minSpacing, { horizontal, minRotation }) { const rad = toRadians(minRotation); const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 1e-3; const length = 0.75 * minSpacing * ("" + value).length; return Math.min(minSpacing / ratio, length); } var LinearScaleBase = class extends Scale { constructor(cfg) { super(cfg); this.start = void 0; this.end = void 0; this._startValue = void 0; this._endValue = void 0; this._valueRange = 0; } parse(raw, index) { if (isNullOrUndef(raw)) { return null; } if ((typeof raw === "number" || raw instanceof Number) && !isFinite(+raw)) { return null; } return +raw; } handleTickRangeOptions() { const { beginAtZero } = this.options; const { minDefined, maxDefined } = this.getUserBounds(); let { min, max } = this; const setMin = (v2) => min = minDefined ? min : v2; const setMax = (v2) => max = maxDefined ? max : v2; if (beginAtZero) { const minSign = sign(min); const maxSign = sign(max); if (minSign < 0 && maxSign < 0) { setMax(0); } else if (minSign > 0 && maxSign > 0) { setMin(0); } } if (min === max) { let offset = max === 0 ? 1 : Math.abs(max * 0.05); setMax(max + offset); if (!beginAtZero) { setMin(min - offset); } } this.min = min; this.max = max; } getTickLimit() { const tickOpts = this.options.ticks; let { maxTicksLimit, stepSize } = tickOpts; let maxTicks; if (stepSize) { maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1; if (maxTicks > 1e3) { console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`); maxTicks = 1e3; } } else { maxTicks = this.computeTickLimit(); maxTicksLimit = maxTicksLimit || 11; } if (maxTicksLimit) { maxTicks = Math.min(maxTicksLimit, maxTicks); } return maxTicks; } computeTickLimit() { return Number.POSITIVE_INFINITY; } buildTicks() { const opts = this.options; const tickOpts = opts.ticks; let maxTicks = this.getTickLimit(); maxTicks = Math.max(2, maxTicks); const numericGeneratorOptions = { maxTicks, bounds: opts.bounds, min: opts.min, max: opts.max, precision: tickOpts.precision, step: tickOpts.stepSize, count: tickOpts.count, maxDigits: this._maxDigits(), horizontal: this.isHorizontal(), minRotation: tickOpts.minRotation || 0, includeBounds: tickOpts.includeBounds !== false }; const dataRange = this._range || this; const ticks = generateTicks$1(numericGeneratorOptions, dataRange); if (opts.bounds === "ticks") { _setMinAndMaxByKey(ticks, this, "value"); } if (opts.reverse) { ticks.reverse(); this.start = this.max; this.end = this.min; } else { this.start = this.min; this.end = this.max; } return ticks; } configure() { const ticks = this.ticks; let start = this.min; let end = this.max; super.configure(); if (this.options.offset && ticks.length) { const offset = (end - start) / Math.max(ticks.length - 1, 1) / 2; start -= offset; end += offset; } this._startValue = start; this._endValue = end; this._valueRange = end - start; } getLabelForValue(value) { return formatNumber(value, this.chart.options.locale, this.options.ticks.format); } }; var LinearScale = class extends LinearScaleBase { determineDataLimits() { const { min, max } = this.getMinMax(true); this.min = isNumberFinite(min) ? min : 0; this.max = isNumberFinite(max) ? max : 1; this.handleTickRangeOptions(); } computeTickLimit() { const horizontal = this.isHorizontal(); const length = horizontal ? this.width : this.height; const minRotation = toRadians(this.options.ticks.minRotation); const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 1e-3; const tickFont = this._resolveTickFontOptions(0); return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio)); } getPixelForValue(value) { return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); } getValueForPixel(pixel) { return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange; } }; __publicField(LinearScale, "id", "linear"); __publicField(LinearScale, "defaults", { ticks: { callback: Ticks.formatters.numeric } }); var log10Floor = (v2) => Math.floor(log10(v2)); var changeExponent = (v2, m2) => Math.pow(10, log10Floor(v2) + m2); function isMajor(tickVal) { const remain = tickVal / Math.pow(10, log10Floor(tickVal)); return remain === 1; } function steps(min, max, rangeExp) { const rangeStep = Math.pow(10, rangeExp); const start = Math.floor(min / rangeStep); const end = Math.ceil(max / rangeStep); return end - start; } function startExp(min, max) { const range = max - min; let rangeExp = log10Floor(range); while (steps(min, max, rangeExp) > 10) { rangeExp++; } while (steps(min, max, rangeExp) < 10) { rangeExp--; } return Math.min(rangeExp, log10Floor(min)); } function generateTicks(generationOptions, { min, max }) { min = finiteOrDefault(generationOptions.min, min); const ticks = []; const minExp = log10Floor(min); let exp = startExp(min, max); let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; const stepSize = Math.pow(10, exp); const base = minExp > exp ? Math.pow(10, minExp) : 0; const start = Math.round((min - base) * precision) / precision; const offset = Math.floor((min - base) / stepSize / 10) * stepSize * 10; let significand = Math.floor((start - offset) / Math.pow(10, exp)); let value = finiteOrDefault(generationOptions.min, Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision); while (value < max) { ticks.push({ value, major: isMajor(value), significand }); if (significand >= 10) { significand = significand < 15 ? 15 : 20; } else { significand++; } if (significand >= 20) { exp++; significand = 2; precision = exp >= 0 ? 1 : precision; } value = Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision; } const lastTick = finiteOrDefault(generationOptions.max, value); ticks.push({ value: lastTick, major: isMajor(lastTick), significand }); return ticks; } var LogarithmicScale = class extends Scale { constructor(cfg) { super(cfg); this.start = void 0; this.end = void 0; this._startValue = void 0; this._valueRange = 0; } parse(raw, index) { const value = LinearScaleBase.prototype.parse.apply(this, [ raw, index ]); if (value === 0) { this._zero = true; return void 0; } return isNumberFinite(value) && value > 0 ? value : null; } determineDataLimits() { const { min, max } = this.getMinMax(true); this.min = isNumberFinite(min) ? Math.max(0, min) : null; this.max = isNumberFinite(max) ? Math.max(0, max) : null; if (this.options.beginAtZero) { this._zero = true; } if (this._zero && this.min !== this._suggestedMin && !isNumberFinite(this._userMin)) { this.min = min === changeExponent(this.min, 0) ? changeExponent(this.min, -1) : changeExponent(this.min, 0); } this.handleTickRangeOptions(); } handleTickRangeOptions() { const { minDefined, maxDefined } = this.getUserBounds(); let min = this.min; let max = this.max; const setMin = (v2) => min = minDefined ? min : v2; const setMax = (v2) => max = maxDefined ? max : v2; if (min === max) { if (min <= 0) { setMin(1); setMax(10); } else { setMin(changeExponent(min, -1)); setMax(changeExponent(max, 1)); } } if (min <= 0) { setMin(changeExponent(max, -1)); } if (max <= 0) { setMax(changeExponent(min, 1)); } this.min = min; this.max = max; } buildTicks() { const opts = this.options; const generationOptions = { min: this._userMin, max: this._userMax }; const ticks = generateTicks(generationOptions, this); if (opts.bounds === "ticks") { _setMinAndMaxByKey(ticks, this, "value"); } if (opts.reverse) { ticks.reverse(); this.start = this.max; this.end = this.min; } else { this.start = this.min; this.end = this.max; } return ticks; } getLabelForValue(value) { return value === void 0 ? "0" : formatNumber(value, this.chart.options.locale, this.options.ticks.format); } configure() { const start = this.min; super.configure(); this._startValue = log10(start); this._valueRange = log10(this.max) - log10(start); } getPixelForValue(value) { if (value === void 0 || value === 0) { value = this.min; } if (value === null || isNaN(value)) { return NaN; } return this.getPixelForDecimal(value === this.min ? 0 : (log10(value) - this._startValue) / this._valueRange); } getValueForPixel(pixel) { const decimal = this.getDecimalForPixel(pixel); return Math.pow(10, this._startValue + decimal * this._valueRange); } }; __publicField(LogarithmicScale, "id", "logarithmic"); __publicField(LogarithmicScale, "defaults", { ticks: { callback: Ticks.formatters.logarithmic, major: { enabled: true } } }); function getTickBackdropHeight(opts) { const tickOpts = opts.ticks; if (tickOpts.display && opts.display) { const padding = toPadding(tickOpts.backdropPadding); return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults2.font.size) + padding.height; } return 0; } function measureLabelSize(ctx, font, label) { label = isArray(label) ? label : [ label ]; return { w: _longestText(ctx, font.string, label), h: label.length * font.lineHeight }; } function determineLimits(angle, pos, size, min, max) { if (angle === min || angle === max) { return { start: pos - size / 2, end: pos + size / 2 }; } else if (angle < min || angle > max) { return { start: pos - size, end: pos }; } return { start: pos, end: pos + size }; } function fitWithPointLabels(scale) { const orig = { l: scale.left + scale._padding.left, r: scale.right - scale._padding.right, t: scale.top + scale._padding.top, b: scale.bottom - scale._padding.bottom }; const limits = Object.assign({}, orig); const labelSizes = []; const padding = []; const valueCount = scale._pointLabels.length; const pointLabelOpts = scale.options.pointLabels; const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0; for (let i2 = 0; i2 < valueCount; i2++) { const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i2)); padding[i2] = opts.padding; const pointPosition = scale.getPointPosition(i2, scale.drawingArea + padding[i2], additionalAngle); const plFont = toFont(opts.font); const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i2]); labelSizes[i2] = textSize; const angleRadians = _normalizeAngle(scale.getIndexAngle(i2) + additionalAngle); const angle = Math.round(toDegrees(angleRadians)); const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); updateLimits(limits, orig, angleRadians, hLimits, vLimits); } scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b); scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding); } function updateLimits(limits, orig, angle, hLimits, vLimits) { const sin = Math.abs(Math.sin(angle)); const cos = Math.abs(Math.cos(angle)); let x2 = 0; let y2 = 0; if (hLimits.start < orig.l) { x2 = (orig.l - hLimits.start) / sin; limits.l = Math.min(limits.l, orig.l - x2); } else if (hLimits.end > orig.r) { x2 = (hLimits.end - orig.r) / sin; limits.r = Math.max(limits.r, orig.r + x2); } if (vLimits.start < orig.t) { y2 = (orig.t - vLimits.start) / cos; limits.t = Math.min(limits.t, orig.t - y2); } else if (vLimits.end > orig.b) { y2 = (vLimits.end - orig.b) / cos; limits.b = Math.max(limits.b, orig.b + y2); } } function createPointLabelItem(scale, index, itemOpts) { const outerDistance = scale.drawingArea; const { extra, additionalAngle, padding, size } = itemOpts; const pointLabelPosition = scale.getPointPosition(index, outerDistance + extra + padding, additionalAngle); const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI))); const y2 = yForAngle(pointLabelPosition.y, size.h, angle); const textAlign = getTextAlignForAngle(angle); const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign); return { visible: true, x: pointLabelPosition.x, y: y2, textAlign, left, top: y2, right: left + size.w, bottom: y2 + size.h }; } function isNotOverlapped(item, area) { if (!area) { return true; } const { left, top, right, bottom } = item; const apexesInArea = _isPointInArea({ x: left, y: top }, area) || _isPointInArea({ x: left, y: bottom }, area) || _isPointInArea({ x: right, y: top }, area) || _isPointInArea({ x: right, y: bottom }, area); return !apexesInArea; } function buildPointLabelItems(scale, labelSizes, padding) { const items = []; const valueCount = scale._pointLabels.length; const opts = scale.options; const { centerPointLabels, display } = opts.pointLabels; const itemOpts = { extra: getTickBackdropHeight(opts) / 2, additionalAngle: centerPointLabels ? PI / valueCount : 0 }; let area; for (let i2 = 0; i2 < valueCount; i2++) { itemOpts.padding = padding[i2]; itemOpts.size = labelSizes[i2]; const item = createPointLabelItem(scale, i2, itemOpts); items.push(item); if (display === "auto") { item.visible = isNotOverlapped(item, area); if (item.visible) { area = item; } } } return items; } function getTextAlignForAngle(angle) { if (angle === 0 || angle === 180) { return "center"; } else if (angle < 180) { return "left"; } return "right"; } function leftForTextAlign(x2, w2, align) { if (align === "right") { x2 -= w2; } else if (align === "center") { x2 -= w2 / 2; } return x2; } function yForAngle(y2, h6, angle) { if (angle === 90 || angle === 270) { y2 -= h6 / 2; } else if (angle > 270 || angle < 90) { y2 -= h6; } return y2; } function drawPointLabelBox(ctx, opts, item) { const { left, top, right, bottom } = item; const { backdropColor } = opts; if (!isNullOrUndef(backdropColor)) { const borderRadius = toTRBLCorners(opts.borderRadius); const padding = toPadding(opts.backdropPadding); ctx.fillStyle = backdropColor; const backdropLeft = left - padding.left; const backdropTop = top - padding.top; const backdropWidth = right - left + padding.width; const backdropHeight = bottom - top + padding.height; if (Object.values(borderRadius).some((v2) => v2 !== 0)) { ctx.beginPath(); addRoundedRectPath(ctx, { x: backdropLeft, y: backdropTop, w: backdropWidth, h: backdropHeight, radius: borderRadius }); ctx.fill(); } else { ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight); } } } function drawPointLabels(scale, labelCount) { const { ctx, options: { pointLabels } } = scale; for (let i2 = labelCount - 1; i2 >= 0; i2--) { const item = scale._pointLabelItems[i2]; if (!item.visible) { continue; } const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i2)); drawPointLabelBox(ctx, optsAtIndex, item); const plFont = toFont(optsAtIndex.font); const { x: x2, y: y2, textAlign } = item; renderText(ctx, scale._pointLabels[i2], x2, y2 + plFont.lineHeight / 2, plFont, { color: optsAtIndex.color, textAlign, textBaseline: "middle" }); } } function pathRadiusLine(scale, radius, circular, labelCount) { const { ctx } = scale; if (circular) { ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU); } else { let pointPosition = scale.getPointPosition(0, radius); ctx.moveTo(pointPosition.x, pointPosition.y); for (let i2 = 1; i2 < labelCount; i2++) { pointPosition = scale.getPointPosition(i2, radius); ctx.lineTo(pointPosition.x, pointPosition.y); } } } function drawRadiusLine(scale, gridLineOpts, radius, labelCount, borderOpts) { const ctx = scale.ctx; const circular = gridLineOpts.circular; const { color: color2, lineWidth } = gridLineOpts; if (!circular && !labelCount || !color2 || !lineWidth || radius < 0) { return; } ctx.save(); ctx.strokeStyle = color2; ctx.lineWidth = lineWidth; ctx.setLineDash(borderOpts.dash); ctx.lineDashOffset = borderOpts.dashOffset; ctx.beginPath(); pathRadiusLine(scale, radius, circular, labelCount); ctx.closePath(); ctx.stroke(); ctx.restore(); } function createPointLabelContext(parent, index, label) { return createContext(parent, { label, index, type: "pointLabel" }); } var RadialLinearScale = class extends LinearScaleBase { constructor(cfg) { super(cfg); this.xCenter = void 0; this.yCenter = void 0; this.drawingArea = void 0; this._pointLabels = []; this._pointLabelItems = []; } setDimensions() { const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2); const w2 = this.width = this.maxWidth - padding.width; const h6 = this.height = this.maxHeight - padding.height; this.xCenter = Math.floor(this.left + w2 / 2 + padding.left); this.yCenter = Math.floor(this.top + h6 / 2 + padding.top); this.drawingArea = Math.floor(Math.min(w2, h6) / 2); } determineDataLimits() { const { min, max } = this.getMinMax(false); this.min = isNumberFinite(min) && !isNaN(min) ? min : 0; this.max = isNumberFinite(max) && !isNaN(max) ? max : 0; this.handleTickRangeOptions(); } computeTickLimit() { return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options)); } generateTickLabels(ticks) { LinearScaleBase.prototype.generateTickLabels.call(this, ticks); this._pointLabels = this.getLabels().map((value, index) => { const label = callback(this.options.pointLabels.callback, [ value, index ], this); return label || label === 0 ? label : ""; }).filter((v2, i2) => this.chart.getDataVisibility(i2)); } fit() { const opts = this.options; if (opts.display && opts.pointLabels.display) { fitWithPointLabels(this); } else { this.setCenterPoint(0, 0, 0, 0); } } setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) { this.xCenter += Math.floor((leftMovement - rightMovement) / 2); this.yCenter += Math.floor((topMovement - bottomMovement) / 2); this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement)); } getIndexAngle(index) { const angleMultiplier = TAU / (this._pointLabels.length || 1); const startAngle = this.options.startAngle || 0; return _normalizeAngle(index * angleMultiplier + toRadians(startAngle)); } getDistanceFromCenterForValue(value) { if (isNullOrUndef(value)) { return NaN; } const scalingFactor = this.drawingArea / (this.max - this.min); if (this.options.reverse) { return (this.max - value) * scalingFactor; } return (value - this.min) * scalingFactor; } getValueForDistanceFromCenter(distance) { if (isNullOrUndef(distance)) { return NaN; } const scaledDistance = distance / (this.drawingArea / (this.max - this.min)); return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance; } getPointLabelContext(index) { const pointLabels = this._pointLabels || []; if (index >= 0 && index < pointLabels.length) { const pointLabel = pointLabels[index]; return createPointLabelContext(this.getContext(), index, pointLabel); } } getPointPosition(index, distanceFromCenter, additionalAngle = 0) { const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle; return { x: Math.cos(angle) * distanceFromCenter + this.xCenter, y: Math.sin(angle) * distanceFromCenter + this.yCenter, angle }; } getPointPositionForValue(index, value) { return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); } getBasePosition(index) { return this.getPointPositionForValue(index || 0, this.getBaseValue()); } getPointLabelPosition(index) { const { left, top, right, bottom } = this._pointLabelItems[index]; return { left, top, right, bottom }; } drawBackground() { const { backgroundColor, grid: { circular } } = this.options; if (backgroundColor) { const ctx = this.ctx; ctx.save(); ctx.beginPath(); pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length); ctx.closePath(); ctx.fillStyle = backgroundColor; ctx.fill(); ctx.restore(); } } drawGrid() { const ctx = this.ctx; const opts = this.options; const { angleLines, grid, border } = opts; const labelCount = this._pointLabels.length; let i2, offset, position; if (opts.pointLabels.display) { drawPointLabels(this, labelCount); } if (grid.display) { this.ticks.forEach((tick, index) => { if (index !== 0 || index === 0 && this.min < 0) { offset = this.getDistanceFromCenterForValue(tick.value); const context = this.getContext(index); const optsAtIndex = grid.setContext(context); const optsAtIndexBorder = border.setContext(context); drawRadiusLine(this, optsAtIndex, offset, labelCount, optsAtIndexBorder); } }); } if (angleLines.display) { ctx.save(); for (i2 = labelCount - 1; i2 >= 0; i2--) { const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i2)); const { color: color2, lineWidth } = optsAtIndex; if (!lineWidth || !color2) { continue; } ctx.lineWidth = lineWidth; ctx.strokeStyle = color2; ctx.setLineDash(optsAtIndex.borderDash); ctx.lineDashOffset = optsAtIndex.borderDashOffset; offset = this.getDistanceFromCenterForValue(opts.reverse ? this.min : this.max); position = this.getPointPosition(i2, offset); ctx.beginPath(); ctx.moveTo(this.xCenter, this.yCenter); ctx.lineTo(position.x, position.y); ctx.stroke(); } ctx.restore(); } } drawBorder() { } drawLabels() { const ctx = this.ctx; const opts = this.options; const tickOpts = opts.ticks; if (!tickOpts.display) { return; } const startAngle = this.getIndexAngle(0); let offset, width; ctx.save(); ctx.translate(this.xCenter, this.yCenter); ctx.rotate(startAngle); ctx.textAlign = "center"; ctx.textBaseline = "middle"; this.ticks.forEach((tick, index) => { if (index === 0 && this.min >= 0 && !opts.reverse) { return; } const optsAtIndex = tickOpts.setContext(this.getContext(index)); const tickFont = toFont(optsAtIndex.font); offset = this.getDistanceFromCenterForValue(this.ticks[index].value); if (optsAtIndex.showLabelBackdrop) { ctx.font = tickFont.string; width = ctx.measureText(tick.label).width; ctx.fillStyle = optsAtIndex.backdropColor; const padding = toPadding(optsAtIndex.backdropPadding); ctx.fillRect(-width / 2 - padding.left, -offset - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height); } renderText(ctx, tick.label, 0, -offset, tickFont, { color: optsAtIndex.color, strokeColor: optsAtIndex.textStrokeColor, strokeWidth: optsAtIndex.textStrokeWidth }); }); ctx.restore(); } drawTitle() { } }; __publicField(RadialLinearScale, "id", "radialLinear"); __publicField(RadialLinearScale, "defaults", { display: true, animate: true, position: "chartArea", angleLines: { display: true, lineWidth: 1, borderDash: [], borderDashOffset: 0 }, grid: { circular: false }, startAngle: 0, ticks: { showLabelBackdrop: true, callback: Ticks.formatters.numeric }, pointLabels: { backdropColor: void 0, backdropPadding: 2, display: true, font: { size: 10 }, callback(label) { return label; }, padding: 5, centerPointLabels: false } }); __publicField(RadialLinearScale, "defaultRoutes", { "angleLines.color": "borderColor", "pointLabels.color": "color", "ticks.color": "color" }); __publicField(RadialLinearScale, "descriptors", { angleLines: { _fallback: "grid" } }); var INTERVALS = { millisecond: { common: true, size: 1, steps: 1e3 }, second: { common: true, size: 1e3, steps: 60 }, minute: { common: true, size: 6e4, steps: 60 }, hour: { common: true, size: 36e5, steps: 24 }, day: { common: true, size: 864e5, steps: 30 }, week: { common: false, size: 6048e5, steps: 4 }, month: { common: true, size: 2628e6, steps: 12 }, quarter: { common: false, size: 7884e6, steps: 4 }, year: { common: true, size: 3154e7 } }; var UNITS = /* @__PURE__ */ Object.keys(INTERVALS); function sorter(a2, b2) { return a2 - b2; } function parse2(scale, input) { if (isNullOrUndef(input)) { return null; } const adapter = scale._adapter; const { parser, round: round2, isoWeekday } = scale._parseOpts; let value = input; if (typeof parser === "function") { value = parser(value); } if (!isNumberFinite(value)) { value = typeof parser === "string" ? adapter.parse(value, parser) : adapter.parse(value); } if (value === null) { return null; } if (round2) { value = round2 === "week" && (isNumber(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, "isoWeek", isoWeekday) : adapter.startOf(value, round2); } return +value; } function determineUnitForAutoTicks(minUnit, min, max, capacity) { const ilen = UNITS.length; for (let i2 = UNITS.indexOf(minUnit); i2 < ilen - 1; ++i2) { const interval = INTERVALS[UNITS[i2]]; const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER; if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { return UNITS[i2]; } } return UNITS[ilen - 1]; } function determineUnitForFormatting(scale, numTicks, minUnit, min, max) { for (let i2 = UNITS.length - 1; i2 >= UNITS.indexOf(minUnit); i2--) { const unit = UNITS[i2]; if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) { return unit; } } return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; } function determineMajorUnit(unit) { for (let i2 = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i2 < ilen; ++i2) { if (INTERVALS[UNITS[i2]].common) { return UNITS[i2]; } } } function addTick(ticks, time, timestamps) { if (!timestamps) { ticks[time] = true; } else if (timestamps.length) { const { lo, hi } = _lookup(timestamps, time); const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi]; ticks[timestamp] = true; } } function setMajorTicks(scale, ticks, map3, majorUnit) { const adapter = scale._adapter; const first = +adapter.startOf(ticks[0].value, majorUnit); const last = ticks[ticks.length - 1].value; let major, index; for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) { index = map3[major]; if (index >= 0) { ticks[index].major = true; } } return ticks; } function ticksFromTimestamps(scale, values, majorUnit) { const ticks = []; const map3 = {}; const ilen = values.length; let i2, value; for (i2 = 0; i2 < ilen; ++i2) { value = values[i2]; map3[value] = i2; ticks.push({ value, major: false }); } return ilen === 0 || !majorUnit ? ticks : setMajorTicks(scale, ticks, map3, majorUnit); } var TimeScale = class extends Scale { constructor(props) { super(props); this._cache = { data: [], labels: [], all: [] }; this._unit = "day"; this._majorUnit = void 0; this._offsets = {}; this._normalized = false; this._parseOpts = void 0; } init(scaleOpts, opts = {}) { const time = scaleOpts.time || (scaleOpts.time = {}); const adapter = this._adapter = new adapters._date(scaleOpts.adapters.date); adapter.init(opts); mergeIf(time.displayFormats, adapter.formats()); this._parseOpts = { parser: time.parser, round: time.round, isoWeekday: time.isoWeekday }; super.init(scaleOpts); this._normalized = opts.normalized; } parse(raw, index) { if (raw === void 0) { return null; } return parse2(this, raw); } beforeLayout() { super.beforeLayout(); this._cache = { data: [], labels: [], all: [] }; } determineDataLimits() { const options = this.options; const adapter = this._adapter; const unit = options.time.unit || "day"; let { min, max, minDefined, maxDefined } = this.getUserBounds(); function _applyBounds(bounds) { if (!minDefined && !isNaN(bounds.min)) { min = Math.min(min, bounds.min); } if (!maxDefined && !isNaN(bounds.max)) { max = Math.max(max, bounds.max); } } if (!minDefined || !maxDefined) { _applyBounds(this._getLabelBounds()); if (options.bounds !== "ticks" || options.ticks.source !== "labels") { _applyBounds(this.getMinMax(false)); } } min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit); max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1; this.min = Math.min(min, max - 1); this.max = Math.max(min + 1, max); } _getLabelBounds() { const arr = this.getLabelTimestamps(); let min = Number.POSITIVE_INFINITY; let max = Number.NEGATIVE_INFINITY; if (arr.length) { min = arr[0]; max = arr[arr.length - 1]; } return { min, max }; } buildTicks() { const options = this.options; const timeOpts = options.time; const tickOpts = options.ticks; const timestamps = tickOpts.source === "labels" ? this.getLabelTimestamps() : this._generate(); if (options.bounds === "ticks" && timestamps.length) { this.min = this._userMin || timestamps[0]; this.max = this._userMax || timestamps[timestamps.length - 1]; } const min = this.min; const max = this.max; const ticks = _filterBetween(timestamps, min, max); this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max)); this._majorUnit = !tickOpts.major.enabled || this._unit === "year" ? void 0 : determineMajorUnit(this._unit); this.initOffsets(timestamps); if (options.reverse) { ticks.reverse(); } return ticksFromTimestamps(this, ticks, this._majorUnit); } afterAutoSkip() { if (this.options.offsetAfterAutoskip) { this.initOffsets(this.ticks.map((tick) => +tick.value)); } } initOffsets(timestamps = []) { let start = 0; let end = 0; let first, last; if (this.options.offset && timestamps.length) { first = this.getDecimalForValue(timestamps[0]); if (timestamps.length === 1) { start = 1 - first; } else { start = (this.getDecimalForValue(timestamps[1]) - first) / 2; } last = this.getDecimalForValue(timestamps[timestamps.length - 1]); if (timestamps.length === 1) { end = last; } else { end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2; } } const limit = timestamps.length < 3 ? 0.5 : 0.25; start = _limitValue(start, 0, limit); end = _limitValue(end, 0, limit); this._offsets = { start, end, factor: 1 / (start + 1 + end) }; } _generate() { const adapter = this._adapter; const min = this.min; const max = this.max; const options = this.options; const timeOpts = options.time; const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min)); const stepSize = valueOrDefault(options.ticks.stepSize, 1); const weekday = minor === "week" ? timeOpts.isoWeekday : false; const hasWeekday = isNumber(weekday) || weekday === true; const ticks = {}; let first = min; let time, count; if (hasWeekday) { first = +adapter.startOf(first, "isoWeek", weekday); } first = +adapter.startOf(first, hasWeekday ? "day" : minor); if (adapter.diff(max, min, minor) > 1e5 * stepSize) { throw new Error(min + " and " + max + " are too far apart with stepSize of " + stepSize + " " + minor); } const timestamps = options.ticks.source === "data" && this.getDataTimestamps(); for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) { addTick(ticks, time, timestamps); } if (time === max || options.bounds === "ticks" || count === 1) { addTick(ticks, time, timestamps); } return Object.keys(ticks).sort(sorter).map((x2) => +x2); } getLabelForValue(value) { const adapter = this._adapter; const timeOpts = this.options.time; if (timeOpts.tooltipFormat) { return adapter.format(value, timeOpts.tooltipFormat); } return adapter.format(value, timeOpts.displayFormats.datetime); } format(value, format) { const options = this.options; const formats = options.time.displayFormats; const unit = this._unit; const fmt = format || formats[unit]; return this._adapter.format(value, fmt); } _tickFormatFunction(time, index, ticks, format) { const options = this.options; const formatter = options.ticks.callback; if (formatter) { return callback(formatter, [ time, index, ticks ], this); } const formats = options.time.displayFormats; const unit = this._unit; const majorUnit = this._majorUnit; const minorFormat = unit && formats[unit]; const majorFormat = majorUnit && formats[majorUnit]; const tick = ticks[index]; const major = majorUnit && majorFormat && tick && tick.major; return this._adapter.format(time, format || (major ? majorFormat : minorFormat)); } generateTickLabels(ticks) { let i2, ilen, tick; for (i2 = 0, ilen = ticks.length; i2 < ilen; ++i2) { tick = ticks[i2]; tick.label = this._tickFormatFunction(tick.value, i2, ticks); } } getDecimalForValue(value) { return value === null ? NaN : (value - this.min) / (this.max - this.min); } getPixelForValue(value) { const offsets = this._offsets; const pos = this.getDecimalForValue(value); return this.getPixelForDecimal((offsets.start + pos) * offsets.factor); } getValueForPixel(pixel) { const offsets = this._offsets; const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; return this.min + pos * (this.max - this.min); } _getLabelSize(label) { const ticksOpts = this.options.ticks; const tickLabelWidth = this.ctx.measureText(label).width; const angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation); const cosRotation = Math.cos(angle); const sinRotation = Math.sin(angle); const tickFontSize = this._resolveTickFontOptions(0).size; return { w: tickLabelWidth * cosRotation + tickFontSize * sinRotation, h: tickLabelWidth * sinRotation + tickFontSize * cosRotation }; } _getLabelCapacity(exampleTime) { const timeOpts = this.options.time; const displayFormats = timeOpts.displayFormats; const format = displayFormats[timeOpts.unit] || displayFormats.millisecond; const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [ exampleTime ], this._majorUnit), format); const size = this._getLabelSize(exampleLabel); const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1; return capacity > 0 ? capacity : 1; } getDataTimestamps() { let timestamps = this._cache.data || []; let i2, ilen; if (timestamps.length) { return timestamps; } const metas = this.getMatchingVisibleMetas(); if (this._normalized && metas.length) { return this._cache.data = metas[0].controller.getAllParsedValues(this); } for (i2 = 0, ilen = metas.length; i2 < ilen; ++i2) { timestamps = timestamps.concat(metas[i2].controller.getAllParsedValues(this)); } return this._cache.data = this.normalize(timestamps); } getLabelTimestamps() { const timestamps = this._cache.labels || []; let i2, ilen; if (timestamps.length) { return timestamps; } const labels = this.getLabels(); for (i2 = 0, ilen = labels.length; i2 < ilen; ++i2) { timestamps.push(parse2(this, labels[i2])); } return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps); } normalize(values) { return _arrayUnique(values.sort(sorter)); } }; __publicField(TimeScale, "id", "time"); __publicField(TimeScale, "defaults", { bounds: "data", adapters: {}, time: { parser: false, unit: false, round: false, isoWeekday: false, minUnit: "millisecond", displayFormats: {} }, ticks: { source: "auto", callback: false, major: { enabled: false } } }); function interpolate3(table, val, reverse) { let lo = 0; let hi = table.length - 1; let prevSource, nextSource, prevTarget, nextTarget; if (reverse) { if (val >= table[lo].pos && val <= table[hi].pos) { ({ lo, hi } = _lookupByKey(table, "pos", val)); } ({ pos: prevSource, time: prevTarget } = table[lo]); ({ pos: nextSource, time: nextTarget } = table[hi]); } else { if (val >= table[lo].time && val <= table[hi].time) { ({ lo, hi } = _lookupByKey(table, "time", val)); } ({ time: prevSource, pos: prevTarget } = table[lo]); ({ time: nextSource, pos: nextTarget } = table[hi]); } const span = nextSource - prevSource; return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget; } var TimeSeriesScale = class extends TimeScale { constructor(props) { super(props); this._table = []; this._minPos = void 0; this._tableRange = void 0; } initOffsets() { const timestamps = this._getTimestampsForTable(); const table = this._table = this.buildLookupTable(timestamps); this._minPos = interpolate3(table, this.min); this._tableRange = interpolate3(table, this.max) - this._minPos; super.initOffsets(timestamps); } buildLookupTable(timestamps) { const { min, max } = this; const items = []; const table = []; let i2, ilen, prev, curr, next; for (i2 = 0, ilen = timestamps.length; i2 < ilen; ++i2) { curr = timestamps[i2]; if (curr >= min && curr <= max) { items.push(curr); } } if (items.length < 2) { return [ { time: min, pos: 0 }, { time: max, pos: 1 } ]; } for (i2 = 0, ilen = items.length; i2 < ilen; ++i2) { next = items[i2 + 1]; prev = items[i2 - 1]; curr = items[i2]; if (Math.round((next + prev) / 2) !== curr) { table.push({ time: curr, pos: i2 / (ilen - 1) }); } } return table; } _generate() { const min = this.min; const max = this.max; let timestamps = super.getDataTimestamps(); if (!timestamps.includes(min) || !timestamps.length) { timestamps.splice(0, 0, min); } if (!timestamps.includes(max) || timestamps.length === 1) { timestamps.push(max); } return timestamps.sort((a2, b2) => a2 - b2); } _getTimestampsForTable() { let timestamps = this._cache.all || []; if (timestamps.length) { return timestamps; } const data = this.getDataTimestamps(); const label = this.getLabelTimestamps(); if (data.length && label.length) { timestamps = this.normalize(data.concat(label)); } else { timestamps = data.length ? data : label; } timestamps = this._cache.all = timestamps; return timestamps; } getDecimalForValue(value) { return (interpolate3(this._table, value) - this._minPos) / this._tableRange; } getValueForPixel(pixel) { const offsets = this._offsets; const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; return interpolate3(this._table, decimal * this._tableRange + this._minPos, true); } }; __publicField(TimeSeriesScale, "id", "timeseries"); __publicField(TimeSeriesScale, "defaults", TimeScale.defaults); // node_modules/.pnpm/gridjs@6.2.0/node_modules/gridjs/dist/gridjs.module.js function t2(t3, n2) { for (var e2 = 0; e2 < n2.length; e2++) { var r2 = n2[e2]; r2.enumerable = r2.enumerable || false, r2.configurable = true, "value" in r2 && (r2.writable = true), Object.defineProperty(t3, "symbol" == typeof (o2 = function(t4, n3) { if ("object" != typeof t4 || null === t4) return t4; var e3 = t4[Symbol.toPrimitive]; if (void 0 !== e3) { var r3 = e3.call(t4, "string"); if ("object" != typeof r3) return r3; throw new TypeError("@@toPrimitive must return a primitive value."); } return String(t4); }(r2.key)) ? o2 : String(o2), r2); } var o2; } function n(n2, e2, r2) { return e2 && t2(n2.prototype, e2), r2 && t2(n2, r2), Object.defineProperty(n2, "prototype", { writable: false }), n2; } function e() { return e = Object.assign ? Object.assign.bind() : function(t3) { for (var n2 = 1; n2 < arguments.length; n2++) { var e2 = arguments[n2]; for (var r2 in e2) Object.prototype.hasOwnProperty.call(e2, r2) && (t3[r2] = e2[r2]); } return t3; }, e.apply(this, arguments); } function r(t3, n2) { t3.prototype = Object.create(n2.prototype), t3.prototype.constructor = t3, o(t3, n2); } function o(t3, n2) { return o = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t4, n3) { return t4.__proto__ = n3, t4; }, o(t3, n2); } function i(t3) { if (void 0 === t3) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return t3; } function u(t3, n2) { (null == n2 || n2 > t3.length) && (n2 = t3.length); for (var e2 = 0, r2 = new Array(n2); e2 < n2; e2++) r2[e2] = t3[e2]; return r2; } function s(t3, n2) { var e2 = "undefined" != typeof Symbol && t3[Symbol.iterator] || t3["@@iterator"]; if (e2) return (e2 = e2.call(t3)).next.bind(e2); if (Array.isArray(t3) || (e2 = function(t4, n3) { if (t4) { if ("string" == typeof t4) return u(t4, n3); var e3 = Object.prototype.toString.call(t4).slice(8, -1); return "Object" === e3 && t4.constructor && (e3 = t4.constructor.name), "Map" === e3 || "Set" === e3 ? Array.from(t4) : "Arguments" === e3 || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e3) ? u(t4, n3) : void 0; } }(t3)) || n2 && t3 && "number" == typeof t3.length) { e2 && (t3 = e2); var r2 = 0; return function() { return r2 >= t3.length ? { done: true } : { done: false, value: t3[r2++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var a; !function(t3) { t3[t3.Init = 0] = "Init", t3[t3.Loading = 1] = "Loading", t3[t3.Loaded = 2] = "Loaded", t3[t3.Rendered = 3] = "Rendered", t3[t3.Error = 4] = "Error"; }(a || (a = {})); var l; var c; var f; var p; var d; var h3; var _; var m = {}; var v = []; var y = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i; function g(t3, n2) { for (var e2 in n2) t3[e2] = n2[e2]; return t3; } function b(t3) { var n2 = t3.parentNode; n2 && n2.removeChild(t3); } function w(t3, n2, e2) { var r2, o2, i2, u2 = {}; for (i2 in n2) "key" == i2 ? r2 = n2[i2] : "ref" == i2 ? o2 = n2[i2] : u2[i2] = n2[i2]; if (arguments.length > 2 && (u2.children = arguments.length > 3 ? l.call(arguments, 2) : e2), "function" == typeof t3 && null != t3.defaultProps) for (i2 in t3.defaultProps) void 0 === u2[i2] && (u2[i2] = t3.defaultProps[i2]); return x(t3, u2, r2, o2, null); } function x(t3, n2, e2, r2, o2) { var i2 = { type: t3, props: n2, key: e2, ref: r2, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, __h: null, constructor: void 0, __v: null == o2 ? ++f : o2 }; return null == o2 && null != c.vnode && c.vnode(i2), i2; } function S(t3) { return t3.children; } function N(t3, n2) { this.props = t3, this.context = n2; } function P(t3, n2) { if (null == n2) return t3.__ ? P(t3.__, t3.__.__k.indexOf(t3) + 1) : null; for (var e2; n2 < t3.__k.length; n2++) if (null != (e2 = t3.__k[n2]) && null != e2.__e) return e2.__e; return "function" == typeof t3.type ? P(t3) : null; } function C(t3) { var n2, e2; if (null != (t3 = t3.__) && null != t3.__c) { for (t3.__e = t3.__c.base = null, n2 = 0; n2 < t3.__k.length; n2++) if (null != (e2 = t3.__k[n2]) && null != e2.__e) { t3.__e = t3.__c.base = e2.__e; break; } return C(t3); } } function E(t3) { (!t3.__d && (t3.__d = true) && d.push(t3) && !I.__r++ || h3 !== c.debounceRendering) && ((h3 = c.debounceRendering) || setTimeout)(I); } function I() { for (var t3; I.__r = d.length; ) t3 = d.sort(function(t4, n2) { return t4.__v.__b - n2.__v.__b; }), d = [], t3.some(function(t4) { var n2, e2, r2, o2, i2, u2; t4.__d && (i2 = (o2 = (n2 = t4).__v).__e, (u2 = n2.__P) && (e2 = [], (r2 = g({}, o2)).__v = o2.__v + 1, M(u2, o2, r2, n2.__n, void 0 !== u2.ownerSVGElement, null != o2.__h ? [i2] : null, e2, null == i2 ? P(o2) : i2, o2.__h), F(e2, o2), o2.__e != i2 && C(o2))); }); } function T(t3, n2, e2, r2, o2, i2, u2, s2, a2, l2) { var c2, f2, p2, d2, h6, _2, y2, g2 = r2 && r2.__k || v, b2 = g2.length; for (e2.__k = [], c2 = 0; c2 < n2.length; c2++) if (null != (d2 = e2.__k[c2] = null == (d2 = n2[c2]) || "boolean" == typeof d2 ? null : "string" == typeof d2 || "number" == typeof d2 || "bigint" == typeof d2 ? x(null, d2, null, null, d2) : Array.isArray(d2) ? x(S, { children: d2 }, null, null, null) : d2.__b > 0 ? x(d2.type, d2.props, d2.key, d2.ref ? d2.ref : null, d2.__v) : d2)) { if (d2.__ = e2, d2.__b = e2.__b + 1, null === (p2 = g2[c2]) || p2 && d2.key == p2.key && d2.type === p2.type) g2[c2] = void 0; else for (f2 = 0; f2 < b2; f2++) { if ((p2 = g2[f2]) && d2.key == p2.key && d2.type === p2.type) { g2[f2] = void 0; break; } p2 = null; } M(t3, d2, p2 = p2 || m, o2, i2, u2, s2, a2, l2), h6 = d2.__e, (f2 = d2.ref) && p2.ref != f2 && (y2 || (y2 = []), p2.ref && y2.push(p2.ref, null, d2), y2.push(f2, d2.__c || h6, d2)), null != h6 ? (null == _2 && (_2 = h6), "function" == typeof d2.type && d2.__k === p2.__k ? d2.__d = a2 = L(d2, a2, t3) : a2 = A(t3, d2, p2, g2, h6, a2), "function" == typeof e2.type && (e2.__d = a2)) : a2 && p2.__e == a2 && a2.parentNode != t3 && (a2 = P(p2)); } for (e2.__e = _2, c2 = b2; c2--; ) null != g2[c2] && W(g2[c2], g2[c2]); if (y2) for (c2 = 0; c2 < y2.length; c2++) U(y2[c2], y2[++c2], y2[++c2]); } function L(t3, n2, e2) { for (var r2, o2 = t3.__k, i2 = 0; o2 && i2 < o2.length; i2++) (r2 = o2[i2]) && (r2.__ = t3, n2 = "function" == typeof r2.type ? L(r2, n2, e2) : A(e2, r2, r2, o2, r2.__e, n2)); return n2; } function A(t3, n2, e2, r2, o2, i2) { var u2, s2, a2; if (void 0 !== n2.__d) u2 = n2.__d, n2.__d = void 0; else if (null == e2 || o2 != i2 || null == o2.parentNode) t: if (null == i2 || i2.parentNode !== t3) t3.appendChild(o2), u2 = null; else { for (s2 = i2, a2 = 0; (s2 = s2.nextSibling) && a2 < r2.length; a2 += 1) if (s2 == o2) break t; t3.insertBefore(o2, i2), u2 = i2; } return void 0 !== u2 ? u2 : o2.nextSibling; } function O(t3, n2, e2) { "-" === n2[0] ? t3.setProperty(n2, e2) : t3[n2] = null == e2 ? "" : "number" != typeof e2 || y.test(n2) ? e2 : e2 + "px"; } function H(t3, n2, e2, r2, o2) { var i2; t: if ("style" === n2) if ("string" == typeof e2) t3.style.cssText = e2; else { if ("string" == typeof r2 && (t3.style.cssText = r2 = ""), r2) for (n2 in r2) e2 && n2 in e2 || O(t3.style, n2, ""); if (e2) for (n2 in e2) r2 && e2[n2] === r2[n2] || O(t3.style, n2, e2[n2]); } else if ("o" === n2[0] && "n" === n2[1]) i2 = n2 !== (n2 = n2.replace(/Capture$/, "")), n2 = n2.toLowerCase() in t3 ? n2.toLowerCase().slice(2) : n2.slice(2), t3.l || (t3.l = {}), t3.l[n2 + i2] = e2, e2 ? r2 || t3.addEventListener(n2, i2 ? D : j, i2) : t3.removeEventListener(n2, i2 ? D : j, i2); else if ("dangerouslySetInnerHTML" !== n2) { if (o2) n2 = n2.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s"); else if ("href" !== n2 && "list" !== n2 && "form" !== n2 && "tabIndex" !== n2 && "download" !== n2 && n2 in t3) try { t3[n2] = null == e2 ? "" : e2; break t; } catch (t4) { } "function" == typeof e2 || (null == e2 || false === e2 && -1 == n2.indexOf("-") ? t3.removeAttribute(n2) : t3.setAttribute(n2, e2)); } } function j(t3) { this.l[t3.type + false](c.event ? c.event(t3) : t3); } function D(t3) { this.l[t3.type + true](c.event ? c.event(t3) : t3); } function M(t3, n2, e2, r2, o2, i2, u2, s2, a2) { var l2, f2, p2, d2, h6, _2, m2, v2, y2, b2, w2, x2, k, P2, C2, E2 = n2.type; if (void 0 !== n2.constructor) return null; null != e2.__h && (a2 = e2.__h, s2 = n2.__e = e2.__e, n2.__h = null, i2 = [s2]), (l2 = c.__b) && l2(n2); try { t: if ("function" == typeof E2) { if (v2 = n2.props, y2 = (l2 = E2.contextType) && r2[l2.__c], b2 = l2 ? y2 ? y2.props.value : l2.__ : r2, e2.__c ? m2 = (f2 = n2.__c = e2.__c).__ = f2.__E : ("prototype" in E2 && E2.prototype.render ? n2.__c = f2 = new E2(v2, b2) : (n2.__c = f2 = new N(v2, b2), f2.constructor = E2, f2.render = B), y2 && y2.sub(f2), f2.props = v2, f2.state || (f2.state = {}), f2.context = b2, f2.__n = r2, p2 = f2.__d = true, f2.__h = [], f2._sb = []), null == f2.__s && (f2.__s = f2.state), null != E2.getDerivedStateFromProps && (f2.__s == f2.state && (f2.__s = g({}, f2.__s)), g(f2.__s, E2.getDerivedStateFromProps(v2, f2.__s))), d2 = f2.props, h6 = f2.state, p2) null == E2.getDerivedStateFromProps && null != f2.componentWillMount && f2.componentWillMount(), null != f2.componentDidMount && f2.__h.push(f2.componentDidMount); else { if (null == E2.getDerivedStateFromProps && v2 !== d2 && null != f2.componentWillReceiveProps && f2.componentWillReceiveProps(v2, b2), !f2.__e && null != f2.shouldComponentUpdate && false === f2.shouldComponentUpdate(v2, f2.__s, b2) || n2.__v === e2.__v) { for (f2.props = v2, f2.state = f2.__s, n2.__v !== e2.__v && (f2.__d = false), f2.__v = n2, n2.__e = e2.__e, n2.__k = e2.__k, n2.__k.forEach(function(t4) { t4 && (t4.__ = n2); }), w2 = 0; w2 < f2._sb.length; w2++) f2.__h.push(f2._sb[w2]); f2._sb = [], f2.__h.length && u2.push(f2); break t; } null != f2.componentWillUpdate && f2.componentWillUpdate(v2, f2.__s, b2), null != f2.componentDidUpdate && f2.__h.push(function() { f2.componentDidUpdate(d2, h6, _2); }); } if (f2.context = b2, f2.props = v2, f2.__v = n2, f2.__P = t3, x2 = c.__r, k = 0, "prototype" in E2 && E2.prototype.render) { for (f2.state = f2.__s, f2.__d = false, x2 && x2(n2), l2 = f2.render(f2.props, f2.state, f2.context), P2 = 0; P2 < f2._sb.length; P2++) f2.__h.push(f2._sb[P2]); f2._sb = []; } else do { f2.__d = false, x2 && x2(n2), l2 = f2.render(f2.props, f2.state, f2.context), f2.state = f2.__s; } while (f2.__d && ++k < 25); f2.state = f2.__s, null != f2.getChildContext && (r2 = g(g({}, r2), f2.getChildContext())), p2 || null == f2.getSnapshotBeforeUpdate || (_2 = f2.getSnapshotBeforeUpdate(d2, h6)), C2 = null != l2 && l2.type === S && null == l2.key ? l2.props.children : l2, T(t3, Array.isArray(C2) ? C2 : [C2], n2, e2, r2, o2, i2, u2, s2, a2), f2.base = n2.__e, n2.__h = null, f2.__h.length && u2.push(f2), m2 && (f2.__E = f2.__ = null), f2.__e = false; } else null == i2 && n2.__v === e2.__v ? (n2.__k = e2.__k, n2.__e = e2.__e) : n2.__e = R(e2.__e, n2, e2, r2, o2, i2, u2, a2); (l2 = c.diffed) && l2(n2); } catch (t4) { n2.__v = null, (a2 || null != i2) && (n2.__e = s2, n2.__h = !!a2, i2[i2.indexOf(s2)] = null), c.__e(t4, n2, e2); } } function F(t3, n2) { c.__c && c.__c(n2, t3), t3.some(function(n3) { try { t3 = n3.__h, n3.__h = [], t3.some(function(t4) { t4.call(n3); }); } catch (t4) { c.__e(t4, n3.__v); } }); } function R(t3, n2, e2, r2, o2, i2, u2, s2) { var a2, c2, f2, p2 = e2.props, d2 = n2.props, h6 = n2.type, _2 = 0; if ("svg" === h6 && (o2 = true), null != i2) { for (; _2 < i2.length; _2++) if ((a2 = i2[_2]) && "setAttribute" in a2 == !!h6 && (h6 ? a2.localName === h6 : 3 === a2.nodeType)) { t3 = a2, i2[_2] = null; break; } } if (null == t3) { if (null === h6) return document.createTextNode(d2); t3 = o2 ? document.createElementNS("http://www.w3.org/2000/svg", h6) : document.createElement(h6, d2.is && d2), i2 = null, s2 = false; } if (null === h6) p2 === d2 || s2 && t3.data === d2 || (t3.data = d2); else { if (i2 = i2 && l.call(t3.childNodes), c2 = (p2 = e2.props || m).dangerouslySetInnerHTML, f2 = d2.dangerouslySetInnerHTML, !s2) { if (null != i2) for (p2 = {}, _2 = 0; _2 < t3.attributes.length; _2++) p2[t3.attributes[_2].name] = t3.attributes[_2].value; (f2 || c2) && (f2 && (c2 && f2.__html == c2.__html || f2.__html === t3.innerHTML) || (t3.innerHTML = f2 && f2.__html || "")); } if (function(t4, n3, e3, r3, o3) { var i3; for (i3 in e3) "children" === i3 || "key" === i3 || i3 in n3 || H(t4, i3, null, e3[i3], r3); for (i3 in n3) o3 && "function" != typeof n3[i3] || "children" === i3 || "key" === i3 || "value" === i3 || "checked" === i3 || e3[i3] === n3[i3] || H(t4, i3, n3[i3], e3[i3], r3); }(t3, d2, p2, o2, s2), f2) n2.__k = []; else if (_2 = n2.props.children, T(t3, Array.isArray(_2) ? _2 : [_2], n2, e2, r2, o2 && "foreignObject" !== h6, i2, u2, i2 ? i2[0] : e2.__k && P(e2, 0), s2), null != i2) for (_2 = i2.length; _2--; ) null != i2[_2] && b(i2[_2]); s2 || ("value" in d2 && void 0 !== (_2 = d2.value) && (_2 !== t3.value || "progress" === h6 && !_2 || "option" === h6 && _2 !== p2.value) && H(t3, "value", _2, p2.value, false), "checked" in d2 && void 0 !== (_2 = d2.checked) && _2 !== t3.checked && H(t3, "checked", _2, p2.checked, false)); } return t3; } function U(t3, n2, e2) { try { "function" == typeof t3 ? t3(n2) : t3.current = n2; } catch (t4) { c.__e(t4, e2); } } function W(t3, n2, e2) { var r2, o2; if (c.unmount && c.unmount(t3), (r2 = t3.ref) && (r2.current && r2.current !== t3.__e || U(r2, null, n2)), null != (r2 = t3.__c)) { if (r2.componentWillUnmount) try { r2.componentWillUnmount(); } catch (t4) { c.__e(t4, n2); } r2.base = r2.__P = null, t3.__c = void 0; } if (r2 = t3.__k) for (o2 = 0; o2 < r2.length; o2++) r2[o2] && W(r2[o2], n2, e2 || "function" != typeof t3.type); e2 || null == t3.__e || b(t3.__e), t3.__ = t3.__e = t3.__d = void 0; } function B(t3, n2, e2) { return this.constructor(t3, e2); } function q(t3, n2, e2) { var r2, o2, i2; c.__ && c.__(t3, n2), o2 = (r2 = "function" == typeof e2) ? null : e2 && e2.__k || n2.__k, i2 = [], M(n2, t3 = (!r2 && e2 || n2).__k = w(S, null, [t3]), o2 || m, m, void 0 !== n2.ownerSVGElement, !r2 && e2 ? [e2] : o2 ? null : n2.firstChild ? l.call(n2.childNodes) : null, i2, !r2 && e2 ? e2 : o2 ? o2.__e : n2.firstChild, r2), F(i2, t3); } function z() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t3) { var n2 = 16 * Math.random() | 0; return ("x" == t3 ? n2 : 3 & n2 | 8).toString(16); }); } l = v.slice, c = { __e: function(t3, n2, e2, r2) { for (var o2, i2, u2; n2 = n2.__; ) if ((o2 = n2.__c) && !o2.__) try { if ((i2 = o2.constructor) && null != i2.getDerivedStateFromError && (o2.setState(i2.getDerivedStateFromError(t3)), u2 = o2.__d), null != o2.componentDidCatch && (o2.componentDidCatch(t3, r2 || {}), u2 = o2.__d), u2) return o2.__E = o2; } catch (n3) { t3 = n3; } throw t3; } }, f = 0, p = function(t3) { return null != t3 && void 0 === t3.constructor; }, N.prototype.setState = function(t3, n2) { var e2; e2 = null != this.__s && this.__s !== this.state ? this.__s : this.__s = g({}, this.state), "function" == typeof t3 && (t3 = t3(g({}, e2), this.props)), t3 && g(e2, t3), null != t3 && this.__v && (n2 && this._sb.push(n2), E(this)); }, N.prototype.forceUpdate = function(t3) { this.__v && (this.__e = true, t3 && this.__h.push(t3), E(this)); }, N.prototype.render = S, d = [], I.__r = 0, _ = 0; var V = /* @__PURE__ */ function() { function t3(t4) { this._id = void 0, this._id = t4 || z(); } return n(t3, [{ key: "id", get: function() { return this._id; } }]), t3; }(); function $(t3) { return w(t3.parentElement || "span", { dangerouslySetInnerHTML: { __html: t3.content } }); } function G(t3, n2) { return w($, { content: t3, parentElement: n2 }); } var K; var X = /* @__PURE__ */ function(t3) { function n2(n3) { var e3; return (e3 = t3.call(this) || this).data = void 0, e3.update(n3), e3; } r(n2, t3); var e2 = n2.prototype; return e2.cast = function(t4) { return t4 instanceof HTMLElement ? G(t4.outerHTML) : t4; }, e2.update = function(t4) { return this.data = this.cast(t4), this; }, n2; }(V); var Z = /* @__PURE__ */ function(t3) { function e2(n2) { var e3; return (e3 = t3.call(this) || this)._cells = void 0, e3.cells = n2 || [], e3; } r(e2, t3); var o2 = e2.prototype; return o2.cell = function(t4) { return this._cells[t4]; }, o2.toArray = function() { return this.cells.map(function(t4) { return t4.data; }); }, e2.fromCells = function(t4) { return new e2(t4.map(function(t5) { return new X(t5.data); })); }, n(e2, [{ key: "cells", get: function() { return this._cells; }, set: function(t4) { this._cells = t4; } }, { key: "length", get: function() { return this.cells.length; } }]), e2; }(V); var J = /* @__PURE__ */ function(t3) { function e2(n2) { var e3; return (e3 = t3.call(this) || this)._rows = void 0, e3._length = void 0, e3.rows = n2 instanceof Array ? n2 : n2 instanceof Z ? [n2] : [], e3; } return r(e2, t3), e2.prototype.toArray = function() { return this.rows.map(function(t4) { return t4.toArray(); }); }, e2.fromRows = function(t4) { return new e2(t4.map(function(t5) { return Z.fromCells(t5.cells); })); }, e2.fromArray = function(t4) { return new e2((t4 = function(t5) { return !t5[0] || t5[0] instanceof Array ? t5 : [t5]; }(t4)).map(function(t5) { return new Z(t5.map(function(t6) { return new X(t6); })); })); }, n(e2, [{ key: "rows", get: function() { return this._rows; }, set: function(t4) { this._rows = t4; } }, { key: "length", get: function() { return this._length || this.rows.length; }, set: function(t4) { this._length = t4; } }]), e2; }(V); var Q = /* @__PURE__ */ function() { function t3() { this.callbacks = void 0; } var n2 = t3.prototype; return n2.init = function(t4) { this.callbacks || (this.callbacks = {}), t4 && !this.callbacks[t4] && (this.callbacks[t4] = []); }, n2.listeners = function() { return this.callbacks; }, n2.on = function(t4, n3) { return this.init(t4), this.callbacks[t4].push(n3), this; }, n2.off = function(t4, n3) { var e2 = t4; return this.init(), this.callbacks[e2] && 0 !== this.callbacks[e2].length ? (this.callbacks[e2] = this.callbacks[e2].filter(function(t5) { return t5 != n3; }), this) : this; }, n2.emit = function(t4) { var n3 = arguments, e2 = t4; return this.init(e2), this.callbacks[e2].length > 0 && (this.callbacks[e2].forEach(function(t5) { return t5.apply(void 0, [].slice.call(n3, 1)); }), true); }, t3; }(); function Y(t3, n2) { if (typeof t3 != typeof n2) return false; if (null === t3 && null === n2) return true; if ("object" != typeof t3) return t3 === n2; if (Array.isArray(t3) && Array.isArray(n2)) { if (t3.length !== n2.length) return false; for (var e2 = 0; e2 < t3.length; e2++) if (!Y(t3[e2], n2[e2])) return false; return true; } if (t3.hasOwnProperty("constructor") && n2.hasOwnProperty("constructor") && t3.hasOwnProperty("props") && n2.hasOwnProperty("props") && t3.hasOwnProperty("key") && n2.hasOwnProperty("key") && t3.hasOwnProperty("ref") && n2.hasOwnProperty("ref") && t3.hasOwnProperty("type") && n2.hasOwnProperty("type")) return Y(t3.props, n2.props); var r2 = Object.keys(t3), o2 = Object.keys(n2); if (r2.length !== o2.length) return false; for (var i2 = 0, u2 = r2; i2 < u2.length; i2++) { var s2 = u2[i2]; if (!n2.hasOwnProperty(s2) || !Y(t3[s2], n2[s2])) return false; } return true; } !function(t3) { t3[t3.Initiator = 0] = "Initiator", t3[t3.ServerFilter = 1] = "ServerFilter", t3[t3.ServerSort = 2] = "ServerSort", t3[t3.ServerLimit = 3] = "ServerLimit", t3[t3.Extractor = 4] = "Extractor", t3[t3.Transformer = 5] = "Transformer", t3[t3.Filter = 6] = "Filter", t3[t3.Sort = 7] = "Sort", t3[t3.Limit = 8] = "Limit"; }(K || (K = {})); var tt = /* @__PURE__ */ function(t3) { function o2(n2) { var e2; return (e2 = t3.call(this) || this).id = void 0, e2._props = void 0, e2._props = {}, e2.id = z(), n2 && e2.setProps(n2), e2; } r(o2, t3); var i2 = o2.prototype; return i2.process = function() { var t4 = [].slice.call(arguments); this.validateProps instanceof Function && this.validateProps.apply(this, t4), this.emit.apply(this, ["beforeProcess"].concat(t4)); var n2 = this._process.apply(this, t4); return this.emit.apply(this, ["afterProcess"].concat(t4)), n2; }, i2.setProps = function(t4) { var n2 = e({}, this._props, t4); return Y(n2, this._props) || (this._props = n2, this.emit("propsUpdated", this)), this; }, n(o2, [{ key: "props", get: function() { return this._props; } }]), o2; }(Q); var nt = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } return r(e2, t3), e2.prototype._process = function(t4) { return this.props.keyword ? (n2 = String(this.props.keyword).trim(), e3 = this.props.columns, r2 = this.props.ignoreHiddenColumns, o2 = t4, i2 = this.props.selector, n2 = n2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), new J(o2.rows.filter(function(t5, o3) { return t5.cells.some(function(t6, u2) { if (!t6) return false; if (r2 && e3 && e3[u2] && "object" == typeof e3[u2] && e3[u2].hidden) return false; var s2 = ""; if ("function" == typeof i2) s2 = i2(t6.data, o3, u2); else if ("object" == typeof t6.data) { var a2 = t6.data; a2 && a2.props && a2.props.content && (s2 = a2.props.content); } else s2 = String(t6.data); return new RegExp(n2, "gi").test(s2); }); }))) : t4; var n2, e3, r2, o2, i2; }, n(e2, [{ key: "type", get: function() { return K.Filter; } }]), e2; }(tt); function et() { var t3 = "gridjs"; return "" + t3 + [].slice.call(arguments).reduce(function(t4, n2) { return t4 + "-" + n2; }, ""); } function rt() { return [].slice.call(arguments).map(function(t3) { return t3 ? t3.toString() : ""; }).filter(function(t3) { return t3; }).reduce(function(t3, n2) { return (t3 || "") + " " + n2; }, "").trim(); } var ot; var it; var ut; var st; var at = /* @__PURE__ */ function(t3) { function o2() { return t3.apply(this, arguments) || this; } return r(o2, t3), o2.prototype._process = function(t4) { if (!this.props.keyword) return t4; var n2 = {}; return this.props.url && (n2.url = this.props.url(t4.url, this.props.keyword)), this.props.body && (n2.body = this.props.body(t4.body, this.props.keyword)), e({}, t4, n2); }, n(o2, [{ key: "type", get: function() { return K.ServerFilter; } }]), o2; }(tt); var lt = 0; var ct = []; var ft = []; var pt = c.__b; var dt = c.__r; var ht = c.diffed; var _t = c.__c; var mt = c.unmount; function vt(t3, n2) { c.__h && c.__h(it, t3, lt || n2), lt = 0; var e2 = it.__H || (it.__H = { __: [], __h: [] }); return t3 >= e2.__.length && e2.__.push({ __V: ft }), e2.__[t3]; } function yt(t3) { return lt = 1, function(t4, n2, e2) { var r2 = vt(ot++, 2); if (r2.t = t4, !r2.__c && (r2.__ = [Et(void 0, n2), function(t5) { var n3 = r2.__N ? r2.__N[0] : r2.__[0], e3 = r2.t(n3, t5); n3 !== e3 && (r2.__N = [e3, r2.__[1]], r2.__c.setState({})); }], r2.__c = it, !it.u)) { it.u = true; var o2 = it.shouldComponentUpdate; it.shouldComponentUpdate = function(t5, n3, e3) { if (!r2.__c.__H) return true; var i2 = r2.__c.__H.__.filter(function(t6) { return t6.__c; }); if (i2.every(function(t6) { return !t6.__N; })) return !o2 || o2.call(this, t5, n3, e3); var u2 = false; return i2.forEach(function(t6) { if (t6.__N) { var n4 = t6.__[0]; t6.__ = t6.__N, t6.__N = void 0, n4 !== t6.__[0] && (u2 = true); } }), !(!u2 && r2.__c.props === t5) && (!o2 || o2.call(this, t5, n3, e3)); }; } return r2.__N || r2.__; }(Et, t3); } function gt(t3, n2) { var e2 = vt(ot++, 3); !c.__s && Ct(e2.__H, n2) && (e2.__ = t3, e2.i = n2, it.__H.__h.push(e2)); } function bt(t3) { return lt = 5, wt(function() { return { current: t3 }; }, []); } function wt(t3, n2) { var e2 = vt(ot++, 7); return Ct(e2.__H, n2) ? (e2.__V = t3(), e2.i = n2, e2.__h = t3, e2.__V) : e2.__; } function xt() { for (var t3; t3 = ct.shift(); ) if (t3.__P && t3.__H) try { t3.__H.__h.forEach(Nt), t3.__H.__h.forEach(Pt), t3.__H.__h = []; } catch (n2) { t3.__H.__h = [], c.__e(n2, t3.__v); } } c.__b = function(t3) { it = null, pt && pt(t3); }, c.__r = function(t3) { dt && dt(t3), ot = 0; var n2 = (it = t3.__c).__H; n2 && (ut === it ? (n2.__h = [], it.__h = [], n2.__.forEach(function(t4) { t4.__N && (t4.__ = t4.__N), t4.__V = ft, t4.__N = t4.i = void 0; })) : (n2.__h.forEach(Nt), n2.__h.forEach(Pt), n2.__h = [])), ut = it; }, c.diffed = function(t3) { ht && ht(t3); var n2 = t3.__c; n2 && n2.__H && (n2.__H.__h.length && (1 !== ct.push(n2) && st === c.requestAnimationFrame || ((st = c.requestAnimationFrame) || St)(xt)), n2.__H.__.forEach(function(t4) { t4.i && (t4.__H = t4.i), t4.__V !== ft && (t4.__ = t4.__V), t4.i = void 0, t4.__V = ft; })), ut = it = null; }, c.__c = function(t3, n2) { n2.some(function(t4) { try { t4.__h.forEach(Nt), t4.__h = t4.__h.filter(function(t5) { return !t5.__ || Pt(t5); }); } catch (e2) { n2.some(function(t5) { t5.__h && (t5.__h = []); }), n2 = [], c.__e(e2, t4.__v); } }), _t && _t(t3, n2); }, c.unmount = function(t3) { mt && mt(t3); var n2, e2 = t3.__c; e2 && e2.__H && (e2.__H.__.forEach(function(t4) { try { Nt(t4); } catch (t5) { n2 = t5; } }), e2.__H = void 0, n2 && c.__e(n2, e2.__v)); }; var kt = "function" == typeof requestAnimationFrame; function St(t3) { var n2, e2 = function() { clearTimeout(r2), kt && cancelAnimationFrame(n2), setTimeout(t3); }, r2 = setTimeout(e2, 100); kt && (n2 = requestAnimationFrame(e2)); } function Nt(t3) { var n2 = it, e2 = t3.__c; "function" == typeof e2 && (t3.__c = void 0, e2()), it = n2; } function Pt(t3) { var n2 = it; t3.__c = t3.__(), it = n2; } function Ct(t3, n2) { return !t3 || t3.length !== n2.length || n2.some(function(n3, e2) { return n3 !== t3[e2]; }); } function Et(t3, n2) { return "function" == typeof n2 ? n2(t3) : n2; } function It() { return function(t3) { var n2 = it.context[t3.__c], e2 = vt(ot++, 9); return e2.c = t3, n2 ? (null == e2.__ && (e2.__ = true, n2.sub(it)), n2.props.value) : t3.__; }(fn); } var Tt = { search: { placeholder: "Type a keyword..." }, sort: { sortAsc: "Sort column ascending", sortDesc: "Sort column descending" }, pagination: { previous: "Previous", next: "Next", navigate: function(t3, n2) { return "Page " + t3 + " of " + n2; }, page: function(t3) { return "Page " + t3; }, showing: "Showing", of: "of", to: "to", results: "results" }, loading: "Loading...", noRecordsFound: "No matching records found", error: "An error happened while fetching the data" }; var Lt = /* @__PURE__ */ function() { function t3(t4) { this._language = void 0, this._defaultLanguage = void 0, this._language = t4, this._defaultLanguage = Tt; } var n2 = t3.prototype; return n2.getString = function(t4, n3) { if (!n3 || !t4) return null; var e2 = t4.split("."), r2 = e2[0]; if (n3[r2]) { var o2 = n3[r2]; return "string" == typeof o2 ? function() { return o2; } : "function" == typeof o2 ? o2 : this.getString(e2.slice(1).join("."), o2); } return null; }, n2.translate = function(t4) { var n3, e2 = this.getString(t4, this._language); return (n3 = e2 || this.getString(t4, this._defaultLanguage)) ? n3.apply(void 0, [].slice.call(arguments, 1)) : t4; }, t3; }(); function At() { var t3 = It(); return function(n2) { var e2; return (e2 = t3.translator).translate.apply(e2, [n2].concat([].slice.call(arguments, 1))); }; } var Ot = function(t3) { return function(n2) { return e({}, n2, { search: { keyword: t3 } }); }; }; function Ht() { return It().store; } function jt(t3) { var n2 = Ht(), e2 = yt(t3(n2.getState())), r2 = e2[0], o2 = e2[1]; return gt(function() { return n2.subscribe(function() { var e3 = t3(n2.getState()); r2 !== e3 && o2(e3); }); }, []), r2; } function Dt() { var t3, n2 = yt(void 0), e2 = n2[0], r2 = n2[1], o2 = It(), i2 = o2.search, u2 = At(), s2 = Ht().dispatch, a2 = jt(function(t4) { return t4.search; }); gt(function() { e2 && e2.setProps({ keyword: null == a2 ? void 0 : a2.keyword }); }, [a2, e2]), gt(function() { r2(i2.server ? new at({ keyword: i2.keyword, url: i2.server.url, body: i2.server.body }) : new nt({ keyword: i2.keyword, columns: o2.header && o2.header.columns, ignoreHiddenColumns: i2.ignoreHiddenColumns || void 0 === i2.ignoreHiddenColumns, selector: i2.selector })), i2.keyword && s2(Ot(i2.keyword)); }, [i2]), gt(function() { if (e2) return o2.pipeline.register(e2), function() { return o2.pipeline.unregister(e2); }; }, [o2, e2]); var l2, c2, f2, p2 = function(t4, n3) { return lt = 8, wt(function() { return t4; }, n3); }((l2 = function(t4) { t4.target instanceof HTMLInputElement && s2(Ot(t4.target.value)); }, c2 = e2 instanceof at ? i2.debounceTimeout || 250 : 0, function() { var t4 = arguments; return new Promise(function(n3) { f2 && clearTimeout(f2), f2 = setTimeout(function() { return n3(l2.apply(void 0, [].slice.call(t4))); }, c2); }); }), [i2, e2]); return w("div", { className: et(rt("search", null == (t3 = o2.className) ? void 0 : t3.search)) }, w("input", { type: "search", placeholder: u2("search.placeholder"), "aria-label": u2("search.placeholder"), onInput: p2, className: rt(et("input"), et("search", "input")), defaultValue: (null == a2 ? void 0 : a2.keyword) || "" })); } var Mt = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } r(e2, t3); var o2 = e2.prototype; return o2.validateProps = function() { if (isNaN(Number(this.props.limit)) || isNaN(Number(this.props.page))) throw Error("Invalid parameters passed"); }, o2._process = function(t4) { var n2 = this.props.page; return new J(t4.rows.slice(n2 * this.props.limit, (n2 + 1) * this.props.limit)); }, n(e2, [{ key: "type", get: function() { return K.Limit; } }]), e2; }(tt); var Ft = /* @__PURE__ */ function(t3) { function o2() { return t3.apply(this, arguments) || this; } return r(o2, t3), o2.prototype._process = function(t4) { var n2 = {}; return this.props.url && (n2.url = this.props.url(t4.url, this.props.page, this.props.limit)), this.props.body && (n2.body = this.props.body(t4.body, this.props.page, this.props.limit)), e({}, t4, n2); }, n(o2, [{ key: "type", get: function() { return K.ServerLimit; } }]), o2; }(tt); function Rt() { var t3 = It(), n2 = t3.pagination, e2 = n2.server, r2 = n2.summary, o2 = void 0 === r2 || r2, i2 = n2.nextButton, u2 = void 0 === i2 || i2, s2 = n2.prevButton, a2 = void 0 === s2 || s2, l2 = n2.buttonsCount, c2 = void 0 === l2 ? 3 : l2, f2 = n2.limit, p2 = void 0 === f2 ? 10 : f2, d2 = n2.page, h6 = void 0 === d2 ? 0 : d2, _2 = n2.resetPageOnUpdate, m2 = void 0 === _2 || _2, v2 = bt(null), y2 = yt(h6), g2 = y2[0], b2 = y2[1], x2 = yt(0), k = x2[0], N2 = x2[1], P2 = At(); gt(function() { return e2 ? (v2.current = new Ft({ limit: p2, page: g2, url: e2.url, body: e2.body }), t3.pipeline.register(v2.current)) : (v2.current = new Mt({ limit: p2, page: g2 }), t3.pipeline.register(v2.current)), v2.current instanceof Ft ? t3.pipeline.on("afterProcess", function(t4) { return N2(t4.length); }) : v2.current instanceof Mt && v2.current.on("beforeProcess", function(t4) { return N2(t4.length); }), t3.pipeline.on("updated", C2), t3.pipeline.on("error", function() { N2(0), b2(0); }), function() { t3.pipeline.unregister(v2.current), t3.pipeline.off("updated", C2); }; }, []); var C2 = function(t4) { m2 && t4 !== v2.current && (b2(0), 0 !== v2.current.props.page && v2.current.setProps({ page: 0 })); }, E2 = function() { return Math.ceil(k / p2); }, I2 = function(t4) { if (t4 >= E2() || t4 < 0 || t4 === g2) return null; b2(t4), v2.current.setProps({ page: t4 }); }; return w("div", { className: rt(et("pagination"), t3.className.pagination) }, w(S, null, o2 && k > 0 && w("div", { role: "status", "aria-live": "polite", className: rt(et("summary"), t3.className.paginationSummary), title: P2("pagination.navigate", g2 + 1, E2()) }, P2("pagination.showing"), " ", w("b", null, P2("" + (g2 * p2 + 1))), " ", P2("pagination.to"), " ", w("b", null, P2("" + Math.min((g2 + 1) * p2, k))), " ", P2("pagination.of"), " ", w("b", null, P2("" + k)), " ", P2("pagination.results"))), w("div", { className: et("pages") }, a2 && w("button", { tabIndex: 0, role: "button", disabled: 0 === g2, onClick: function() { return I2(g2 - 1); }, title: P2("pagination.previous"), "aria-label": P2("pagination.previous"), className: rt(t3.className.paginationButton, t3.className.paginationButtonPrev) }, P2("pagination.previous")), function() { if (c2 <= 0) return null; var n3 = Math.min(E2(), c2), e3 = Math.min(g2, Math.floor(n3 / 2)); return g2 + Math.floor(n3 / 2) >= E2() && (e3 = n3 - (E2() - g2)), w(S, null, E2() > n3 && g2 - e3 > 0 && w(S, null, w("button", { tabIndex: 0, role: "button", onClick: function() { return I2(0); }, title: P2("pagination.firstPage"), "aria-label": P2("pagination.firstPage"), className: t3.className.paginationButton }, P2("1")), w("button", { tabIndex: -1, className: rt(et("spread"), t3.className.paginationButton) }, "...")), Array.from(Array(n3).keys()).map(function(t4) { return g2 + (t4 - e3); }).map(function(n4) { return w("button", { tabIndex: 0, role: "button", onClick: function() { return I2(n4); }, className: rt(g2 === n4 ? rt(et("currentPage"), t3.className.paginationButtonCurrent) : null, t3.className.paginationButton), title: P2("pagination.page", n4 + 1), "aria-label": P2("pagination.page", n4 + 1) }, P2("" + (n4 + 1))); }), E2() > n3 && E2() > g2 + e3 + 1 && w(S, null, w("button", { tabIndex: -1, className: rt(et("spread"), t3.className.paginationButton) }, "..."), w("button", { tabIndex: 0, role: "button", onClick: function() { return I2(E2() - 1); }, title: P2("pagination.page", E2()), "aria-label": P2("pagination.page", E2()), className: t3.className.paginationButton }, P2("" + E2())))); }(), u2 && w("button", { tabIndex: 0, role: "button", disabled: E2() === g2 + 1 || 0 === E2(), onClick: function() { return I2(g2 + 1); }, title: P2("pagination.next"), "aria-label": P2("pagination.next"), className: rt(t3.className.paginationButton, t3.className.paginationButtonNext) }, P2("pagination.next")))); } function Ut(t3, n2) { return "string" == typeof t3 ? t3.indexOf("%") > -1 ? n2 / 100 * parseInt(t3, 10) : parseInt(t3, 10) : t3; } function Wt(t3) { return t3 ? Math.floor(t3) + "px" : ""; } function Bt(t3) { var n2 = t3.tableRef.cloneNode(true); return n2.style.position = "absolute", n2.style.width = "100%", n2.style.zIndex = "-2147483640", n2.style.visibility = "hidden", w("div", { ref: function(t4) { t4 && t4.appendChild(n2); } }); } function qt(t3) { if (!t3) return ""; var n2 = t3.split(" "); return 1 === n2.length && /([a-z][A-Z])+/g.test(t3) ? t3 : n2.map(function(t4, n3) { return 0 == n3 ? t4.toLowerCase() : t4.charAt(0).toUpperCase() + t4.slice(1).toLowerCase(); }).join(""); } var zt; var Vt = new (/* @__PURE__ */ function() { function t3() { } var n2 = t3.prototype; return n2.format = function(t4, n3) { return "[Grid.js] [" + n3.toUpperCase() + "]: " + t4; }, n2.error = function(t4, n3) { void 0 === n3 && (n3 = false); var e2 = this.format(t4, "error"); if (n3) throw Error(e2); console.error(e2); }, n2.warn = function(t4) { console.warn(this.format(t4, "warn")); }, n2.info = function(t4) { console.info(this.format(t4, "info")); }, t3; }())(); !function(t3) { t3[t3.Header = 0] = "Header", t3[t3.Footer = 1] = "Footer", t3[t3.Cell = 2] = "Cell"; }(zt || (zt = {})); var $t = /* @__PURE__ */ function() { function t3() { this.plugins = void 0, this.plugins = []; } var n2 = t3.prototype; return n2.get = function(t4) { return this.plugins.find(function(n3) { return n3.id === t4; }); }, n2.add = function(t4) { return t4.id ? this.get(t4.id) ? (Vt.error("Duplicate plugin ID: " + t4.id), this) : (this.plugins.push(t4), this) : (Vt.error("Plugin ID cannot be empty"), this); }, n2.remove = function(t4) { var n3 = this.get(t4); return n3 && this.plugins.splice(this.plugins.indexOf(n3), 1), this; }, n2.list = function(t4) { var n3; return n3 = null != t4 || null != t4 ? this.plugins.filter(function(n4) { return n4.position === t4; }) : this.plugins, n3.sort(function(t5, n4) { return t5.order && n4.order ? t5.order - n4.order : 1; }); }, t3; }(); function Gt(t3) { var n2 = this, r2 = It(); if (t3.pluginId) { var o2 = r2.plugin.get(t3.pluginId); return o2 ? w(S, {}, w(o2.component, e({ plugin: o2 }, t3.props))) : null; } return void 0 !== t3.position ? w(S, {}, r2.plugin.list(t3.position).map(function(t4) { return w(t4.component, e({ plugin: t4 }, n2.props.props)); })) : null; } var Kt = /* @__PURE__ */ function(t3) { function o2() { var n2; return (n2 = t3.call(this) || this)._columns = void 0, n2._columns = [], n2; } r(o2, t3); var i2 = o2.prototype; return i2.adjustWidth = function(t4, n2, r2) { var i3 = t4.container, u2 = t4.autoWidth; if (!i3) return this; var a2 = i3.clientWidth, l2 = {}; n2.current && u2 && (q(w(Bt, { tableRef: n2.current }), r2.current), l2 = function(t5) { var n3 = t5.querySelector("table"); if (!n3) return {}; var r3 = n3.className, o3 = n3.style.cssText; n3.className = r3 + " " + et("shadowTable"), n3.style.tableLayout = "auto", n3.style.width = "auto", n3.style.padding = "0", n3.style.margin = "0", n3.style.border = "none", n3.style.outline = "none"; var i4 = Array.from(n3.parentNode.querySelectorAll("thead th")).reduce(function(t6, n4) { var r4; return n4.style.width = n4.clientWidth + "px", e(((r4 = {})[n4.getAttribute("data-column-id")] = { minWidth: n4.clientWidth }, r4), t6); }, {}); return n3.className = r3, n3.style.cssText = o3, n3.style.tableLayout = "auto", Array.from(n3.parentNode.querySelectorAll("thead th")).reduce(function(t6, n4) { return t6[n4.getAttribute("data-column-id")].width = n4.clientWidth, t6; }, i4); }(r2.current)); for (var c2, f2 = s(o2.tabularFormat(this.columns).reduce(function(t5, n3) { return t5.concat(n3); }, [])); !(c2 = f2()).done; ) { var p2 = c2.value; p2.columns && p2.columns.length > 0 || (!p2.width && u2 ? p2.id in l2 && (p2.width = Wt(l2[p2.id].width), p2.minWidth = Wt(l2[p2.id].minWidth)) : p2.width = Wt(Ut(p2.width, a2))); } return n2.current && u2 && q(null, r2.current), this; }, i2.setSort = function(t4, n2) { for (var r2, o3 = s(n2 || this.columns || []); !(r2 = o3()).done; ) { var i3 = r2.value; i3.columns && i3.columns.length > 0 ? i3.sort = void 0 : void 0 === i3.sort && t4 ? i3.sort = {} : i3.sort ? "object" == typeof i3.sort && (i3.sort = e({}, i3.sort)) : i3.sort = void 0, i3.columns && this.setSort(t4, i3.columns); } }, i2.setResizable = function(t4, n2) { for (var e2, r2 = s(n2 || this.columns || []); !(e2 = r2()).done; ) { var o3 = e2.value; void 0 === o3.resizable && (o3.resizable = t4), o3.columns && this.setResizable(t4, o3.columns); } }, i2.setID = function(t4) { for (var n2, e2 = s(t4 || this.columns || []); !(n2 = e2()).done; ) { var r2 = n2.value; r2.id || "string" != typeof r2.name || (r2.id = qt(r2.name)), r2.id || Vt.error('Could not find a valid ID for one of the columns. Make sure a valid "id" is set for all columns.'), r2.columns && this.setID(r2.columns); } }, i2.populatePlugins = function(t4, n2) { for (var r2, o3 = s(n2); !(r2 = o3()).done; ) { var i3 = r2.value; void 0 !== i3.plugin && t4.add(e({ id: i3.id }, i3.plugin, { position: zt.Cell })); } }, o2.fromColumns = function(t4) { for (var n2, e2 = new o2(), r2 = s(t4); !(n2 = r2()).done; ) { var i3 = n2.value; if ("string" == typeof i3 || p(i3)) e2.columns.push({ name: i3 }); else if ("object" == typeof i3) { var u2 = i3; u2.columns && (u2.columns = o2.fromColumns(u2.columns).columns), "object" == typeof u2.plugin && void 0 === u2.data && (u2.data = null), e2.columns.push(i3); } } return e2; }, o2.createFromConfig = function(t4) { var n2 = new o2(); return t4.from ? n2.columns = o2.fromHTMLTable(t4.from).columns : t4.columns ? n2.columns = o2.fromColumns(t4.columns).columns : !t4.data || "object" != typeof t4.data[0] || t4.data[0] instanceof Array || (n2.columns = Object.keys(t4.data[0]).map(function(t5) { return { name: t5 }; })), n2.columns.length ? (n2.setID(), n2.setSort(t4.sort), n2.setResizable(t4.resizable), n2.populatePlugins(t4.plugin, n2.columns), n2) : null; }, o2.fromHTMLTable = function(t4) { for (var n2, e2 = new o2(), r2 = s(t4.querySelector("thead").querySelectorAll("th")); !(n2 = r2()).done; ) { var i3 = n2.value; e2.columns.push({ name: i3.innerHTML, width: i3.width }); } return e2; }, o2.tabularFormat = function(t4) { var n2 = [], e2 = t4 || [], r2 = []; if (e2 && e2.length) { n2.push(e2); for (var o3, i3 = s(e2); !(o3 = i3()).done; ) { var u2 = o3.value; u2.columns && u2.columns.length && (r2 = r2.concat(u2.columns)); } r2.length && (n2 = n2.concat(this.tabularFormat(r2))); } return n2; }, o2.leafColumns = function(t4) { var n2 = [], e2 = t4 || []; if (e2 && e2.length) for (var r2, o3 = s(e2); !(r2 = o3()).done; ) { var i3 = r2.value; i3.columns && 0 !== i3.columns.length || n2.push(i3), i3.columns && (n2 = n2.concat(this.leafColumns(i3.columns))); } return n2; }, o2.maximumDepth = function(t4) { return this.tabularFormat([t4]).length - 1; }, n(o2, [{ key: "columns", get: function() { return this._columns; }, set: function(t4) { this._columns = t4; } }, { key: "visibleColumns", get: function() { return this._columns.filter(function(t4) { return !t4.hidden; }); } }]), o2; }(V); var Xt = function() { }; var Zt = /* @__PURE__ */ function(t3) { function n2(n3) { var e3; return (e3 = t3.call(this) || this).data = void 0, e3.set(n3), e3; } r(n2, t3); var e2 = n2.prototype; return e2.get = function() { try { return Promise.resolve(this.data()).then(function(t4) { return { data: t4, total: t4.length }; }); } catch (t4) { return Promise.reject(t4); } }, e2.set = function(t4) { return t4 instanceof Array ? this.data = function() { return t4; } : t4 instanceof Function && (this.data = t4), this; }, n2; }(Xt); var Jt = /* @__PURE__ */ function(t3) { function n2(n3) { var e2; return (e2 = t3.call(this) || this).options = void 0, e2.options = n3, e2; } r(n2, t3); var o2 = n2.prototype; return o2.handler = function(t4) { return "function" == typeof this.options.handle ? this.options.handle(t4) : t4.ok ? t4.json() : (Vt.error("Could not fetch data: " + t4.status + " - " + t4.statusText, true), null); }, o2.get = function(t4) { var n3 = e({}, this.options, t4); return "function" == typeof n3.data ? n3.data(n3) : fetch(n3.url, n3).then(this.handler.bind(this)).then(function(t5) { return { data: n3.then(t5), total: "function" == typeof n3.total ? n3.total(t5) : void 0 }; }); }, n2; }(Xt); var Qt = /* @__PURE__ */ function() { function t3() { } return t3.createFromConfig = function(t4) { var n2 = null; return t4.data && (n2 = new Zt(t4.data)), t4.from && (n2 = new Zt(this.tableElementToArray(t4.from)), t4.from.style.display = "none"), t4.server && (n2 = new Jt(t4.server)), n2 || Vt.error("Could not determine the storage type", true), n2; }, t3.tableElementToArray = function(t4) { for (var n2, e2, r2 = [], o2 = s(t4.querySelector("tbody").querySelectorAll("tr")); !(n2 = o2()).done; ) { for (var i2, u2 = [], a2 = s(n2.value.querySelectorAll("td")); !(i2 = a2()).done; ) { var l2 = i2.value; 1 === l2.childNodes.length && l2.childNodes[0].nodeType === Node.TEXT_NODE ? u2.push((e2 = l2.innerHTML, new DOMParser().parseFromString(e2, "text/html").documentElement.textContent)) : u2.push(G(l2.innerHTML)); } r2.push(u2); } return r2; }, t3; }(); var Yt = "undefined" != typeof Symbol ? Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator")) : "@@iterator"; function tn(t3, n2, e2) { if (!t3.s) { if (e2 instanceof nn) { if (!e2.s) return void (e2.o = tn.bind(null, t3, n2)); 1 & n2 && (n2 = e2.s), e2 = e2.v; } if (e2 && e2.then) return void e2.then(tn.bind(null, t3, n2), tn.bind(null, t3, 2)); t3.s = n2, t3.v = e2; var r2 = t3.o; r2 && r2(t3); } } var nn = /* @__PURE__ */ function() { function t3() { } return t3.prototype.then = function(n2, e2) { var r2 = new t3(), o2 = this.s; if (o2) { var i2 = 1 & o2 ? n2 : e2; if (i2) { try { tn(r2, 1, i2(this.v)); } catch (t4) { tn(r2, 2, t4); } return r2; } return this; } return this.o = function(t4) { try { var o3 = t4.v; 1 & t4.s ? tn(r2, 1, n2 ? n2(o3) : o3) : e2 ? tn(r2, 1, e2(o3)) : tn(r2, 2, o3); } catch (t5) { tn(r2, 2, t5); } }, r2; }, t3; }(); function en(t3) { return t3 instanceof nn && 1 & t3.s; } var rn = /* @__PURE__ */ function(t3) { function e2(n2) { var e3; return (e3 = t3.call(this) || this)._steps = /* @__PURE__ */ new Map(), e3.cache = /* @__PURE__ */ new Map(), e3.lastProcessorIndexUpdated = -1, n2 && n2.forEach(function(t4) { return e3.register(t4); }), e3; } r(e2, t3); var o2 = e2.prototype; return o2.clearCache = function() { this.cache = /* @__PURE__ */ new Map(), this.lastProcessorIndexUpdated = -1; }, o2.register = function(t4, n2) { if (void 0 === n2 && (n2 = null), !t4) throw Error("Processor is not defined"); if (null === t4.type) throw Error("Processor type is not defined"); if (this.findProcessorIndexByID(t4.id) > -1) throw Error("Processor ID " + t4.id + " is already defined"); return t4.on("propsUpdated", this.processorPropsUpdated.bind(this)), this.addProcessorByPriority(t4, n2), this.afterRegistered(t4), t4; }, o2.tryRegister = function(t4, n2) { void 0 === n2 && (n2 = null); try { return this.register(t4, n2); } catch (t5) { } }, o2.unregister = function(t4) { if (t4 && -1 !== this.findProcessorIndexByID(t4.id)) { var n2 = this._steps.get(t4.type); n2 && n2.length && (this._steps.set(t4.type, n2.filter(function(n3) { return n3 != t4; })), this.emit("updated", t4)); } }, o2.addProcessorByPriority = function(t4, n2) { var e3 = this._steps.get(t4.type); if (!e3) { var r2 = []; this._steps.set(t4.type, r2), e3 = r2; } if (null === n2 || n2 < 0) e3.push(t4); else if (e3[n2]) { var o3 = e3.slice(0, n2 - 1), i2 = e3.slice(n2 + 1); this._steps.set(t4.type, o3.concat(t4).concat(i2)); } else e3[n2] = t4; }, o2.getStepsByType = function(t4) { return this.steps.filter(function(n2) { return n2.type === t4; }); }, o2.getSortedProcessorTypes = function() { return Object.keys(K).filter(function(t4) { return !isNaN(Number(t4)); }).map(function(t4) { return Number(t4); }); }, o2.process = function(t4) { try { var n2 = function(t5) { return e3.lastProcessorIndexUpdated = o3.length, e3.emit("afterProcess", i2), i2; }, e3 = this, r2 = e3.lastProcessorIndexUpdated, o3 = e3.steps, i2 = t4, u2 = function(t5, n3) { try { var u3 = function(t6, n4, e4) { if ("function" == typeof t6[Yt]) { var r3, o4, i3, u4 = t6[Yt](); if (function t7(e5) { try { for (; !(r3 = u4.next()).done; ) if ((e5 = n4(r3.value)) && e5.then) { if (!en(e5)) return void e5.then(t7, i3 || (i3 = tn.bind(null, o4 = new nn(), 2))); e5 = e5.v; } o4 ? tn(o4, 1, e5) : o4 = e5; } catch (t8) { tn(o4 || (o4 = new nn()), 2, t8); } }(), u4.return) { var s2 = function(t7) { try { r3.done || u4.return(); } catch (t8) { } return t7; }; if (o4 && o4.then) return o4.then(s2, function(t7) { throw s2(t7); }); s2(); } return o4; } if (!("length" in t6)) throw new TypeError("Object is not iterable"); for (var a2 = [], l2 = 0; l2 < t6.length; l2++) a2.push(t6[l2]); return function(t7, n5, e5) { var r4, o5, i4 = -1; return function e6(u5) { try { for (; ++i4 < t7.length; ) if ((u5 = n5(i4)) && u5.then) { if (!en(u5)) return void u5.then(e6, o5 || (o5 = tn.bind(null, r4 = new nn(), 2))); u5 = u5.v; } r4 ? tn(r4, 1, u5) : r4 = u5; } catch (t8) { tn(r4 || (r4 = new nn()), 2, t8); } }(), r4; }(a2, function(t7) { return n4(a2[t7]); }); }(o3, function(t6) { var n4 = e3.findProcessorIndexByID(t6.id), o4 = function() { if (n4 >= r2) return Promise.resolve(t6.process(i2)).then(function(n5) { e3.cache.set(t6.id, i2 = n5); }); i2 = e3.cache.get(t6.id); }(); if (o4 && o4.then) return o4.then(function() { }); }); } catch (t6) { return n3(t6); } return u3 && u3.then ? u3.then(void 0, n3) : u3; }(0, function(t5) { throw Vt.error(t5), e3.emit("error", i2), t5; }); return Promise.resolve(u2 && u2.then ? u2.then(n2) : n2()); } catch (t5) { return Promise.reject(t5); } }, o2.findProcessorIndexByID = function(t4) { return this.steps.findIndex(function(n2) { return n2.id == t4; }); }, o2.setLastProcessorIndex = function(t4) { var n2 = this.findProcessorIndexByID(t4.id); this.lastProcessorIndexUpdated > n2 && (this.lastProcessorIndexUpdated = n2); }, o2.processorPropsUpdated = function(t4) { this.setLastProcessorIndex(t4), this.emit("propsUpdated"), this.emit("updated", t4); }, o2.afterRegistered = function(t4) { this.setLastProcessorIndex(t4), this.emit("afterRegister"), this.emit("updated", t4); }, n(e2, [{ key: "steps", get: function() { for (var t4, n2 = [], e3 = s(this.getSortedProcessorTypes()); !(t4 = e3()).done; ) { var r2 = this._steps.get(t4.value); r2 && r2.length && (n2 = n2.concat(r2)); } return n2.filter(function(t5) { return t5; }); } }]), e2; }(Q); var on = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } return r(e2, t3), e2.prototype._process = function(t4) { try { return Promise.resolve(this.props.storage.get(t4)); } catch (t5) { return Promise.reject(t5); } }, n(e2, [{ key: "type", get: function() { return K.Extractor; } }]), e2; }(tt); var un = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } return r(e2, t3), e2.prototype._process = function(t4) { var n2 = J.fromArray(t4.data); return n2.length = t4.total, n2; }, n(e2, [{ key: "type", get: function() { return K.Transformer; } }]), e2; }(tt); var sn = /* @__PURE__ */ function(t3) { function o2() { return t3.apply(this, arguments) || this; } return r(o2, t3), o2.prototype._process = function() { return Object.entries(this.props.serverStorageOptions).filter(function(t4) { return "function" != typeof t4[1]; }).reduce(function(t4, n2) { var r2; return e({}, t4, ((r2 = {})[n2[0]] = n2[1], r2)); }, {}); }, n(o2, [{ key: "type", get: function() { return K.Initiator; } }]), o2; }(tt); var an = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } r(e2, t3); var o2 = e2.prototype; return o2.castData = function(t4) { if (!t4 || !t4.length) return []; if (!this.props.header || !this.props.header.columns) return t4; var n2 = Kt.leafColumns(this.props.header.columns); return t4[0] instanceof Array ? t4.map(function(t5) { var e3 = 0; return n2.map(function(n3, r2) { return void 0 !== n3.data ? (e3++, "function" == typeof n3.data ? n3.data(t5) : n3.data) : t5[r2 - e3]; }); }) : "object" != typeof t4[0] || t4[0] instanceof Array ? [] : t4.map(function(t5) { return n2.map(function(n3, e3) { return void 0 !== n3.data ? "function" == typeof n3.data ? n3.data(t5) : n3.data : n3.id ? t5[n3.id] : (Vt.error("Could not find the correct cell for column at position " + e3 + ".\n Make sure either 'id' or 'selector' is defined for all columns."), null); }); }); }, o2._process = function(t4) { return { data: this.castData(t4.data), total: t4.total }; }, n(e2, [{ key: "type", get: function() { return K.Transformer; } }]), e2; }(tt); var ln = /* @__PURE__ */ function() { function t3() { } return t3.createFromConfig = function(t4) { var n2 = new rn(); return t4.storage instanceof Jt && n2.register(new sn({ serverStorageOptions: t4.server })), n2.register(new on({ storage: t4.storage })), n2.register(new an({ header: t4.header })), n2.register(new un()), n2; }, t3; }(); var cn = function(t3) { var n2 = this; this.state = void 0, this.listeners = [], this.isDispatching = false, this.getState = function() { return n2.state; }, this.getListeners = function() { return n2.listeners; }, this.dispatch = function(t4) { if ("function" != typeof t4) throw new Error("Reducer is not a function"); if (n2.isDispatching) throw new Error("Reducers may not dispatch actions"); n2.isDispatching = true; var e2 = n2.state; try { n2.state = t4(n2.state); } finally { n2.isDispatching = false; } for (var r2, o2 = s(n2.listeners); !(r2 = o2()).done; ) (0, r2.value)(n2.state, e2); return n2.state; }, this.subscribe = function(t4) { if ("function" != typeof t4) throw new Error("Listener is not a function"); return n2.listeners = [].concat(n2.listeners, [t4]), function() { return n2.listeners = n2.listeners.filter(function(n3) { return n3 !== t4; }); }; }, this.state = t3; }; var fn = function(t3, n2) { var e2 = { __c: n2 = "__cC" + _++, __: null, Consumer: function(t4, n3) { return t4.children(n3); }, Provider: function(t4) { var e3, r2; return this.getChildContext || (e3 = [], (r2 = {})[n2] = this, this.getChildContext = function() { return r2; }, this.shouldComponentUpdate = function(t5) { this.props.value !== t5.value && e3.some(E); }, this.sub = function(t5) { e3.push(t5); var n3 = t5.componentWillUnmount; t5.componentWillUnmount = function() { e3.splice(e3.indexOf(t5), 1), n3 && n3.call(t5); }; }), t4.children; } }; return e2.Provider.__ = e2.Consumer.contextType = e2; }(); var pn = /* @__PURE__ */ function() { function t3() { Object.assign(this, t3.defaultConfig()); } var n2 = t3.prototype; return n2.assign = function(t4) { return Object.assign(this, t4); }, n2.update = function(n3) { return n3 ? (this.assign(t3.fromPartialConfig(e({}, this, n3))), this) : this; }, t3.defaultConfig = function() { return { store: new cn({ status: a.Init, header: void 0, data: null }), plugin: new $t(), tableRef: { current: null }, width: "100%", height: "auto", processingThrottleMs: 100, autoWidth: true, style: {}, className: {} }; }, t3.fromPartialConfig = function(n3) { var e2 = new t3().assign(n3); return "boolean" == typeof n3.sort && n3.sort && e2.assign({ sort: { multiColumn: true } }), e2.assign({ header: Kt.createFromConfig(e2) }), e2.assign({ storage: Qt.createFromConfig(e2) }), e2.assign({ pipeline: ln.createFromConfig(e2) }), e2.assign({ translator: new Lt(e2.language) }), e2.plugin = new $t(), e2.search && e2.plugin.add({ id: "search", position: zt.Header, component: Dt }), e2.pagination && e2.plugin.add({ id: "pagination", position: zt.Footer, component: Rt }), e2.plugins && e2.plugins.forEach(function(t4) { return e2.plugin.add(t4); }), e2; }, t3; }(); function dn(t3) { var n2, r2 = It(); return w("td", e({ role: t3.role, colSpan: t3.colSpan, "data-column-id": t3.column && t3.column.id, className: rt(et("td"), t3.className, r2.className.td), style: e({}, t3.style, r2.style.td), onClick: function(n3) { t3.messageCell || r2.eventEmitter.emit("cellClick", n3, t3.cell, t3.column, t3.row); } }, (n2 = t3.column) ? "function" == typeof n2.attributes ? n2.attributes(t3.cell.data, t3.row, t3.column) : n2.attributes : {}), t3.column && "function" == typeof t3.column.formatter ? t3.column.formatter(t3.cell.data, t3.row, t3.column) : t3.column && t3.column.plugin ? w(Gt, { pluginId: t3.column.id, props: { column: t3.column, cell: t3.cell, row: t3.row } }) : t3.cell.data); } function hn(t3) { var n2 = It(), e2 = jt(function(t4) { return t4.header; }); return w("tr", { className: rt(et("tr"), n2.className.tr), onClick: function(e3) { t3.messageRow || n2.eventEmitter.emit("rowClick", e3, t3.row); } }, t3.children ? t3.children : t3.row.cells.map(function(n3, r2) { var o2 = function(t4) { if (e2) { var n4 = Kt.leafColumns(e2.columns); if (n4) return n4[t4]; } return null; }(r2); return o2 && o2.hidden ? null : w(dn, { key: n3.id, cell: n3, row: t3.row, column: o2 }); })); } function _n(t3) { return w(hn, { messageRow: true }, w(dn, { role: "alert", colSpan: t3.colSpan, messageCell: true, cell: new X(t3.message), className: rt(et("message"), t3.className ? t3.className : null) })); } function mn() { var t3 = It(), n2 = jt(function(t4) { return t4.data; }), e2 = jt(function(t4) { return t4.status; }), r2 = jt(function(t4) { return t4.header; }), o2 = At(), i2 = function() { return r2 ? r2.visibleColumns.length : 0; }; return w("tbody", { className: rt(et("tbody"), t3.className.tbody) }, n2 && n2.rows.map(function(t4) { return w(hn, { key: t4.id, row: t4 }); }), e2 === a.Loading && (!n2 || 0 === n2.length) && w(_n, { message: o2("loading"), colSpan: i2(), className: rt(et("loading"), t3.className.loading) }), e2 === a.Rendered && n2 && 0 === n2.length && w(_n, { message: o2("noRecordsFound"), colSpan: i2(), className: rt(et("notfound"), t3.className.notfound) }), e2 === a.Error && w(_n, { message: o2("error"), colSpan: i2(), className: rt(et("error"), t3.className.error) })); } var vn = /* @__PURE__ */ function(t3) { function e2() { return t3.apply(this, arguments) || this; } r(e2, t3); var o2 = e2.prototype; return o2.validateProps = function() { for (var t4, n2 = s(this.props.columns); !(t4 = n2()).done; ) { var e3 = t4.value; void 0 === e3.direction && (e3.direction = 1), 1 !== e3.direction && -1 !== e3.direction && Vt.error("Invalid sort direction " + e3.direction); } }, o2.compare = function(t4, n2) { return t4 > n2 ? 1 : t4 < n2 ? -1 : 0; }, o2.compareWrapper = function(t4, n2) { for (var e3, r2 = 0, o3 = s(this.props.columns); !(e3 = o3()).done; ) { var i2 = e3.value; if (0 !== r2) break; var u2 = t4.cells[i2.index].data, a2 = n2.cells[i2.index].data; r2 |= "function" == typeof i2.compare ? i2.compare(u2, a2) * i2.direction : this.compare(u2, a2) * i2.direction; } return r2; }, o2._process = function(t4) { var n2 = [].concat(t4.rows); n2.sort(this.compareWrapper.bind(this)); var e3 = new J(n2); return e3.length = t4.length, e3; }, n(e2, [{ key: "type", get: function() { return K.Sort; } }]), e2; }(tt); var yn = function(t3, n2, r2, o2) { return function(i2) { var u2, s2 = null != (u2 = i2.sort) && u2.columns ? i2.sort.columns.map(function(t4) { return e({}, t4); }) : [], a2 = s2.length, l2 = s2.find(function(n3) { return n3.index === t3; }), c2 = false, f2 = false, p2 = false, d2 = false; if (void 0 !== l2 ? r2 ? -1 === l2.direction ? p2 = true : d2 = true : 1 === a2 ? d2 = true : a2 > 1 && (f2 = true, c2 = true) : 0 === a2 ? c2 = true : a2 > 0 && !r2 ? (c2 = true, f2 = true) : a2 > 0 && r2 && (c2 = true), f2 && (s2 = []), c2) s2.push({ index: t3, direction: n2, compare: o2 }); else if (d2) { var h6 = s2.indexOf(l2); s2[h6].direction = n2; } else if (p2) { var _2 = s2.indexOf(l2); s2.splice(_2, 1); } return e({}, i2, { sort: { columns: s2 } }); }; }; var gn = function(t3, n2, r2) { return function(o2) { var i2 = (o2.sort ? [].concat(o2.sort.columns) : []).find(function(n3) { return n3.index === t3; }); return e({}, o2, i2 ? yn(t3, 1 === i2.direction ? -1 : 1, n2, r2)(o2) : yn(t3, 1, n2, r2)(o2)); }; }; var bn = /* @__PURE__ */ function(t3) { function o2() { return t3.apply(this, arguments) || this; } return r(o2, t3), o2.prototype._process = function(t4) { var n2 = {}; return this.props.url && (n2.url = this.props.url(t4.url, this.props.columns)), this.props.body && (n2.body = this.props.body(t4.body, this.props.columns)), e({}, t4, n2); }, n(o2, [{ key: "type", get: function() { return K.ServerSort; } }]), o2; }(tt); function wn(t3) { var n2 = It(), r2 = Ht().dispatch, o2 = At(), i2 = yt(0), u2 = i2[0], s2 = i2[1], a2 = n2.sort, l2 = jt(function(t4) { return t4.sort; }), c2 = "object" == typeof (null == a2 ? void 0 : a2.server) ? K.ServerSort : K.Sort, f2 = function() { var t4 = n2.pipeline.getStepsByType(c2); if (t4.length) return t4[0]; }; return gt(function() { var t4 = f2() || (c2 === K.ServerSort ? new bn(e({ columns: l2 ? l2.columns : [] }, a2.server)) : new vn({ columns: l2 ? l2.columns : [] })); return n2.pipeline.tryRegister(t4), function() { return n2.pipeline.unregister(t4); }; }, [n2]), gt(function() { if (l2) { var n3, e2 = l2.columns.find(function(n4) { return n4.index === t3.index; }); e2 ? (0 === u2 && (e2.direction = null != (n3 = t3.direction) ? n3 : 1), s2(e2.direction)) : s2(0); } }, [l2]), gt(function() { var t4 = f2(); t4 && l2 && t4.setProps({ columns: l2.columns }); }, [l2]), w("button", { tabIndex: -1, "aria-label": o2("sort.sort" + (1 === u2 ? "Desc" : "Asc")), title: o2("sort.sort" + (1 === u2 ? "Desc" : "Asc")), className: rt(et("sort"), et("sort", /* @__PURE__ */ function(t4) { return 1 === t4 ? "asc" : -1 === t4 ? "desc" : "neutral"; }(u2)), n2.className.sort), onClick: function(n3) { n3.preventDefault(), n3.stopPropagation(), r2(gn(t3.index, true === n3.shiftKey && a2.multiColumn, t3.compare)); } }); } var xn = function(t3, n2) { var e2; void 0 === n2 && (n2 = 100); var r2 = Date.now(), o2 = function() { r2 = Date.now(), t3.apply(void 0, [].slice.call(arguments)); }; return function() { var t4 = [].slice.call(arguments), i2 = Date.now(), u2 = i2 - r2; u2 >= n2 ? o2.apply(void 0, t4) : (e2 && clearTimeout(e2), e2 = setTimeout(function() { o2.apply(void 0, t4), e2 = null; }, n2 - u2)); }; }; function kn(t3) { var n2, e2 = function(t4) { return t4 instanceof MouseEvent ? Math.floor(t4.pageX) : Math.floor(t4.changedTouches[0].pageX); }, r2 = function(r3) { r3.stopPropagation(); var u2 = parseInt(t3.thRef.current.style.width, 10) - e2(r3); n2 = xn(function(t4) { return o2(t4, u2); }, 10), document.addEventListener("mouseup", i2), document.addEventListener("touchend", i2), document.addEventListener("mousemove", n2), document.addEventListener("touchmove", n2); }, o2 = function(n3, r3) { n3.stopPropagation(); var o3 = t3.thRef.current; r3 + e2(n3) >= parseInt(o3.style.minWidth, 10) && (o3.style.width = r3 + e2(n3) + "px"); }, i2 = function t4(e3) { e3.stopPropagation(), document.removeEventListener("mouseup", t4), document.removeEventListener("mousemove", n2), document.removeEventListener("touchmove", n2), document.removeEventListener("touchend", t4); }; return w("div", { className: rt(et("th"), et("resizable")), onMouseDown: r2, onTouchStart: r2, onClick: function(t4) { return t4.stopPropagation(); } }); } function Sn(t3) { var n2 = It(), r2 = bt(null), o2 = yt({}), i2 = o2[0], u2 = o2[1], s2 = Ht().dispatch; gt(function() { if (n2.fixedHeader && r2.current) { var t4 = r2.current.offsetTop; "number" == typeof t4 && u2({ top: t4 }); } }, [r2]); var a2, l2 = function() { return null != t3.column.sort; }, c2 = function(e2) { e2.stopPropagation(), l2() && s2(gn(t3.index, true === e2.shiftKey && n2.sort.multiColumn, t3.column.sort.compare)); }; return w("th", e({ ref: r2, "data-column-id": t3.column && t3.column.id, className: rt(et("th"), l2() ? et("th", "sort") : null, n2.fixedHeader ? et("th", "fixed") : null, n2.className.th), onClick: c2, style: e({}, n2.style.th, { minWidth: t3.column.minWidth, width: t3.column.width }, i2, t3.style), onKeyDown: function(t4) { l2() && 13 === t4.which && c2(t4); }, rowSpan: t3.rowSpan > 1 ? t3.rowSpan : void 0, colSpan: t3.colSpan > 1 ? t3.colSpan : void 0 }, (a2 = t3.column) ? "function" == typeof a2.attributes ? a2.attributes(null, null, t3.column) : a2.attributes : {}, l2() ? { tabIndex: 0 } : {}), w("div", { className: et("th", "content") }, void 0 !== t3.column.name ? t3.column.name : void 0 !== t3.column.plugin ? w(Gt, { pluginId: t3.column.plugin.id, props: { column: t3.column } }) : null), l2() && w(wn, e({ index: t3.index }, t3.column.sort)), t3.column.resizable && t3.index < n2.header.visibleColumns.length - 1 && w(kn, { column: t3.column, thRef: r2 })); } function Nn() { var t3, n2 = It(), e2 = jt(function(t4) { return t4.header; }); return e2 ? w("thead", { key: e2.id, className: rt(et("thead"), n2.className.thead) }, (t3 = Kt.tabularFormat(e2.columns)).map(function(n3, r2) { return function(t4, n4, r3) { var o2 = Kt.leafColumns(e2.columns); return w(hn, null, t4.map(function(t5) { return t5.hidden ? null : function(t6, n5, e3, r4) { var o3 = function(t7, n6, e4) { var r5 = Kt.maximumDepth(t7), o4 = e4 - n6; return { rowSpan: Math.floor(o4 - r5 - r5 / o4), colSpan: t7.columns && t7.columns.length || 1 }; }(t6, n5, r4); return w(Sn, { column: t6, index: e3, colSpan: o3.colSpan, rowSpan: o3.rowSpan }); }(t5, n4, o2.indexOf(t5), r3); })); }(n3, r2, t3.length); })) : null; } var Pn = function(t3) { return function(n2) { return e({}, n2, { header: t3 }); }; }; function Cn() { var t3 = It(), n2 = bt(null), r2 = Ht().dispatch; return gt(function() { n2 && r2(/* @__PURE__ */ function(t4) { return function(n3) { return e({}, n3, { tableRef: t4 }); }; }(n2)); }, [n2]), w("table", { ref: n2, role: "grid", className: rt(et("table"), t3.className.table), style: e({}, t3.style.table, { height: t3.height }) }, w(Nn, null), w(mn, null)); } function En() { var t3 = yt(true), n2 = t3[0], r2 = t3[1], o2 = bt(null), i2 = It(); return gt(function() { 0 === o2.current.children.length && r2(false); }, [o2]), n2 ? w("div", { ref: o2, className: rt(et("head"), i2.className.header), style: e({}, i2.style.header) }, w(Gt, { position: zt.Header })) : null; } function In() { var t3 = bt(null), n2 = yt(true), r2 = n2[0], o2 = n2[1], i2 = It(); return gt(function() { 0 === t3.current.children.length && o2(false); }, [t3]), r2 ? w("div", { ref: t3, className: rt(et("footer"), i2.className.footer), style: e({}, i2.style.footer) }, w(Gt, { position: zt.Footer })) : null; } function Tn() { var t3 = It(), n2 = Ht().dispatch, r2 = jt(function(t4) { return t4.status; }), o2 = jt(function(t4) { return t4.data; }), i2 = jt(function(t4) { return t4.tableRef; }), u2 = { current: null }, s2 = xn(function() { try { n2(function(t4) { return e({}, t4, { status: a.Loading }); }); var r3 = function(r4, o3) { try { var i3 = Promise.resolve(t3.pipeline.process()).then(function(t4) { n2(/* @__PURE__ */ function(t5) { return function(n3) { return t5 ? e({}, n3, { data: t5, status: a.Loaded }) : n3; }; }(t4)), setTimeout(function() { n2(function(t5) { return t5.status === a.Loaded ? e({}, t5, { status: a.Rendered }) : t5; }); }, 0); }); } catch (t4) { return o3(t4); } return i3 && i3.then ? i3.then(void 0, o3) : i3; }(0, function(t4) { Vt.error(t4), n2(function(t5) { return e({}, t5, { data: null, status: a.Error }); }); }); return Promise.resolve(r3 && r3.then ? r3.then(function() { }) : void 0); } catch (t4) { return Promise.reject(t4); } }, t3.processingThrottleMs); return gt(function() { return n2(Pn(t3.header)), s2(), t3.pipeline.on("updated", s2), function() { return t3.pipeline.off("updated", s2); }; }, []), gt(function() { t3.header && r2 === a.Loaded && null != o2 && o2.length && n2(Pn(t3.header.adjustWidth(t3, i2, u2))); }, [o2, t3, u2]), w("div", { role: "complementary", className: rt("gridjs", et("container"), r2 === a.Loading ? et("loading") : null, t3.className.container), style: e({}, t3.style.container, { width: t3.width }) }, r2 === a.Loading && w("div", { className: et("loading-bar") }), w(En, null), w("div", { className: et("wrapper"), style: { height: t3.height } }, w(Cn, null)), w(In, null), w("div", { ref: u2, id: "gridjs-temp", className: et("temp") })); } var Ln = /* @__PURE__ */ function(t3) { function n2(n3) { var e3; return (e3 = t3.call(this) || this).config = void 0, e3.plugin = void 0, e3.config = new pn().assign({ instance: i(e3), eventEmitter: i(e3) }).update(n3), e3.plugin = e3.config.plugin, e3; } r(n2, t3); var e2 = n2.prototype; return e2.updateConfig = function(t4) { return this.config.update(t4), this; }, e2.createElement = function() { return w(fn.Provider, { value: this.config, children: w(Tn, {}) }); }, e2.forceRender = function() { return this.config && this.config.container || Vt.error("Container is empty. Make sure you call render() before forceRender()", true), this.destroy(), q(this.createElement(), this.config.container), this; }, e2.destroy = function() { this.config.pipeline.clearCache(), q(null, this.config.container); }, e2.render = function(t4) { return t4 || Vt.error("Container element cannot be null", true), t4.childNodes.length > 0 ? (Vt.error("The container element " + t4 + " is not empty. Make sure the container is empty and call render() again"), this) : (this.config.container = t4, q(this.createElement(), t4), this); }, n2; }(Q); // src/gui/statistics.tsx var import_path = __toESM(require("path")); var import_vhtml2 = __toESM(require_vhtml()); Chart.register( BarElement, BarController, plugin_legend, plugin_title, plugin_tooltip, plugin_subtitle, CategoryScale, LinearScale, PieController, ArcElement ); var StatisticsView = class { constructor(containerEl, osrCore) { this.containerEl = containerEl; this.osrCore = osrCore; } render() { this.containerEl.style.textAlign = "center"; this.containerEl.innerHTML += /* @__PURE__ */ (0, import_vhtml2.default)("select", { id: "sr-chart-period" }, /* @__PURE__ */ (0, import_vhtml2.default)("option", { value: "month", selected: true }, t("MONTH")), /* @__PURE__ */ (0, import_vhtml2.default)("option", { value: "quarter" }, t("QUARTER")), /* @__PURE__ */ (0, import_vhtml2.default)("option", { value: "year" }, t("YEAR")), /* @__PURE__ */ (0, import_vhtml2.default)("option", { value: "lifetime" }, t("LIFETIME"))); const cardStats = this.osrCore.cardStats; let maxN = cardStats.delayedDays.getMaxValue(); for (let dueOffset = 0; dueOffset <= maxN; dueOffset++) { cardStats.delayedDays.clearCountIfMissing(dueOffset); } const dueDatesFlashcardsCopy = { 0: 0 }; for (const [dueOffset, dueCount] of getTypedObjectEntries(cardStats.delayedDays.dict)) { if (dueOffset <= 0) { dueDatesFlashcardsCopy[0] += dueCount; } else { dueDatesFlashcardsCopy[dueOffset] = dueCount; } } const scheduledCount = cardStats.youngCount + cardStats.matureCount; maxN = Math.max(maxN, 1); this.containerEl.innerHTML += /* @__PURE__ */ (0, import_vhtml2.default)("div", null, /* @__PURE__ */ (0, import_vhtml2.default)("canvas", { id: "forecastChart" }), /* @__PURE__ */ (0, import_vhtml2.default)("span", { id: "forecastChartSummary" }), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("canvas", { id: "intervalsChart" }), /* @__PURE__ */ (0, import_vhtml2.default)("span", { id: "intervalsChartSummary" }), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("canvas", { id: "easesChart" }), /* @__PURE__ */ (0, import_vhtml2.default)("span", { id: "easesChartSummary" }), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("canvas", { id: "cardTypesChart" }), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("span", { id: "cardTypesChartSummary" }), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("br", null), /* @__PURE__ */ (0, import_vhtml2.default)("h1", null, "Notes"), /* @__PURE__ */ (0, import_vhtml2.default)("div", { id: "noteStats" })); this.forecastChart = createStatsChart( "bar", "forecastChart", t("FORECAST"), t("FORECAST_DESC"), Object.keys(dueDatesFlashcardsCopy), Object.values(dueDatesFlashcardsCopy), t("REVIEWS_PER_DAY", { avg: (scheduledCount / maxN).toFixed(1) }), t("SCHEDULED"), t("DAYS"), t("NUMBER_OF_CARDS") ); maxN = cardStats.intervals.getMaxValue(); for (let interval = 0; interval <= maxN; interval++) { cardStats.intervals.clearCountIfMissing(interval); } const averageInterval = textInterval( Math.round( cardStats.intervals.getTotalOfValueMultiplyCount() / scheduledCount * 10 ) / 10 || 0, false ), longestInterval = textInterval(cardStats.intervals.getMaxValue(), false); this.intervalsChart = createStatsChart( "bar", "intervalsChart", t("INTERVALS"), t("INTERVALS_DESC"), Object.keys(cardStats.intervals.dict), Object.values(cardStats.intervals.dict), t("INTERVALS_SUMMARY", { avg: averageInterval, longest: longestInterval }), t("COUNT"), t("DAYS"), t("NUMBER_OF_CARDS") ); const eases = getKeysPreserveType(cardStats.eases.dict); for (let ease = Math.min(...eases); ease <= Math.max(...eases); ease++) { cardStats.eases.clearCountIfMissing(ease); } const averageEase = Math.round(cardStats.eases.getTotalOfValueMultiplyCount() / scheduledCount) || 0; this.easesChart = createStatsChart( "bar", "easesChart", t("EASES"), "", Object.keys(cardStats.eases.dict), Object.values(cardStats.eases.dict), t("EASES_SUMMARY", { avgEase: averageEase }), t("COUNT"), t("EASES"), t("NUMBER_OF_CARDS") ); const totalCardsCount = this.osrCore.reviewableDeckTree.getDistinctCardCount( 2 /* All */, true ); this.cardTypesChart = createStatsChart( "pie", "cardTypesChart", t("CARD_TYPES"), t("CARD_TYPES_DESC"), [ `${t("CARD_TYPE_NEW")} - ${Math.round(cardStats.newCount / totalCardsCount * 100)}%`, `${t("CARD_TYPE_YOUNG")} - ${Math.round( cardStats.youngCount / totalCardsCount * 100 )}%`, `${t("CARD_TYPE_MATURE")} - ${Math.round( cardStats.matureCount / totalCardsCount * 100 )}%` ], [cardStats.newCount, cardStats.youngCount, cardStats.matureCount], t("CARD_TYPES_SUMMARY", { totalCardsCount }) ); const noteEases = mapRecord( SrsAlgorithm.getInstance().noteStats().dict, (key, value) => [ import_path.default.parse(key).name, Math.round(value) ] ); this.noteStatsGrid = new Ln({ columns: [ { name: t("NOTE") }, { name: t("EASE"), sort: true, width: "200px" } ], search: true, autoWidth: false, data: Object.entries(noteEases).sort((a2, b2) => b2[1] - a2[1]), pagination: { limit: 10, summary: false }, language: { search: { placeholder: t("SEARCH") }, pagination: { previous: t("PREVIOUS"), next: t("NEXT") } } }); this.noteStatsGrid.render(document.getElementById("noteStats")); } destroy() { this.forecastChart.destroy(); this.intervalsChart.destroy(); this.easesChart.destroy(); this.cardTypesChart.destroy(); this.noteStatsGrid.destroy(); } }; function createStatsChart(type, canvasId, title, subtitle, labels, data, summary, seriesTitle = "", xAxisTitle = "", yAxisTitle = "") { const style = getComputedStyle(document.body); const textColor = style.getPropertyValue("--text-normal"); let scales = {}, backgroundColor = ["#2196f3"]; if (type !== "pie") { scales = { x: { title: { display: true, text: xAxisTitle, color: textColor } }, y: { title: { display: true, text: yAxisTitle, color: textColor } } }; } else { backgroundColor = ["#2196f3", "#4caf50", "green"]; } const shouldFilter = canvasId === "forecastChart" || canvasId === "intervalsChart"; const statsChart = new Chart(document.getElementById(canvasId), { type, data: { labels: shouldFilter ? labels.slice(0, 31) : labels, datasets: [ { label: seriesTitle, backgroundColor, data: shouldFilter ? data.slice(0, 31) : data } ] }, options: { scales, plugins: { title: { display: true, text: title, font: { size: 22 }, color: textColor }, subtitle: { display: true, text: subtitle, font: { size: 16, style: "italic" }, color: textColor }, legend: { display: false } }, aspectRatio: 2 } }); if (shouldFilter) { const chartPeriodEl = document.getElementById("sr-chart-period"); chartPeriodEl.addEventListener("click", () => { let filteredLabels, filteredData; const chartPeriod = chartPeriodEl.value; if (chartPeriod === "month") { filteredLabels = labels.slice(0, 31); filteredData = data.slice(0, 31); } else if (chartPeriod === "quarter") { filteredLabels = labels.slice(0, 91); filteredData = data.slice(0, 91); } else if (chartPeriod === "year") { filteredLabels = labels.slice(0, 366); filteredData = data.slice(0, 366); } else { filteredLabels = labels; filteredData = data; } statsChart.data.labels = filteredLabels; statsChart.data.datasets[0] = { label: seriesTitle, backgroundColor, data: filteredData }; statsChart.update(); }); } document.getElementById(`${canvasId}Summary`).innerText = summary; return statsChart; } // src/gui/tabs.tsx var import_obsidian9 = require("obsidian"); var import_vhtml3 = __toESM(require_vhtml()); function createTabs(containerElement, tabs, activateTabId) { const tabHeader = containerElement.createEl("div", { attr: { class: "sr-tab-header" } }); const tabContentContainers = {}; const tabButtons = {}; const tabStructure = { header: tabHeader, // Indicate that the first tab is active. // This does not affect what tab is active in practice, it just reports the active tab. activeTabId: Object.keys(tabs)[0], buttons: tabButtons, contentContainers: tabContentContainers, contentGeneratorPromises: {} }; let firstButton; for (const tabId in tabs) { const tab = tabs[tabId]; const button = tabHeader.createEl("button", { attr: { class: "sr-tab-header-button", activateTab: "sr-tab-" + tabId } }); button.onclick = function(event) { var _a; const tabButton = this; let maxWidth = 0; let maxHeight = 0; const tabHeader2 = tabButton.parentElement; if (null === tabHeader2) { throw new Error("Tab header is missing. Did not get a parent from tab button."); } const containerElement2 = tabHeader2.parentElement; if (null === containerElement2) { throw new Error( "Container element is missing. Did not get a parent from tab header." ); } const tabContents = containerElement2.findAll("div.sr-tab-content"); const isMainSettingsModal = containerElement2.hasClass("vertical-tab-content"); for (const index in tabContents) { const tabContent2 = tabContents[index]; if (!isMainSettingsModal) { tabContent2.addClass("sr-tab-active"); if (tabContent2.offsetHeight > maxHeight) { maxHeight = tabContent2.offsetHeight; } if (tabContent2.offsetWidth > maxWidth) { maxWidth = tabContent2.offsetWidth; } } tabContent2.removeClass("sr-tab-active"); } const adjacentTabButtons = tabHeader2.findAll(".sr-tab-header-button"); for (const index in adjacentTabButtons) { const tabButton2 = adjacentTabButtons[index]; tabButton2.removeClass("sr-tab-active"); } tabButton.addClass("sr-tab-active"); const activateTabAttribute = tabButton.attributes.getNamedItem("activateTab"); if (null === activateTabAttribute) { throw new Error("Tab button has no 'activateTab' HTML attribute! Murr!"); } const activateTabId2 = activateTabAttribute.value; const tabContent = document.getElementById(activateTabId2); if (null === tabContent) { throw new Error( "No tab content was found with activate_tab_id '" + activateTabId2 + "'! Hmph!" ); } tabContent.addClass("sr-tab-active"); tabStructure.activeTabId = activateTabId2.replace(/^sr-tab-/, ""); (_a = tabContent.find(".sr-focus-element-on-tab-opening")) == null ? void 0 : _a.focus(); if (!isMainSettingsModal) { tabContent.style.width = maxWidth + "px"; tabContent.style.height = maxHeight + "px"; } event.preventDefault(); }; if (tab.icon) (0, import_obsidian9.setIcon)(button, tab.icon); button.insertAdjacentHTML("beforeend", /* @__PURE__ */ (0, import_vhtml3.default)("span", { style: "padding-left: 5px;" }, tab.title)); tabButtons[tabId] = button; tabContentContainers[tabId] = containerElement.createEl("div", { attr: { class: "sr-tab-content", id: "sr-tab-" + tabId } }); tabStructure.contentGeneratorPromises[tabId] = tab.contentGenerator( tabContentContainers[tabId] ); if (void 0 === firstButton) { firstButton = button; } } tabButtons[activateTabId].click(); return tabStructure; } // src/gui/settings.tsx var applyDebounceTimer = 0; function applySettingsUpdate(callback2) { clearTimeout(applyDebounceTimer); applyDebounceTimer = window.setTimeout(callback2, 512); } var SRSettingTab = class extends import_obsidian10.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.lastPosition = { scrollPosition: 0, tabName: "main-flashcards" }; this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); const header = containerEl.createEl("h4", { text: `${t("SETTINGS_HEADER")}` }); header.addClass("sr-centered"); this.tabStructure = createTabs( containerEl, { "main-flashcards": { title: t("FLASHCARDS"), icon: "SpacedRepIcon", contentGenerator: (containerElement) => this.tabFlashcards(containerElement) }, "main-notes": { title: t("NOTES"), icon: "book-text", contentGenerator: (containerElement) => this.tabNotes(containerElement) }, "main-algorithm": { title: t("SCHEDULING"), icon: "calendar", contentGenerator: (containerElement) => this.tabScheduling(containerElement) }, "main-ui-preferences": { title: t("UI"), icon: "presentation", contentGenerator: (containerElement) => this.tabUiPreferences(containerElement) }, "main-statistics": { title: t("STATS_TITLE"), icon: "bar-chart-3", contentGenerator: async (containerElement) => { if (this.plugin.osrAppCore.cardStats == null) { await this.plugin.sync(); } this.statistics = new StatisticsView( containerElement, this.plugin.osrAppCore ); this.statistics.render(); } }, "main-help": { title: t("HELP"), icon: "badge-help", contentGenerator: (containerElement) => this.tabHelp(containerElement) } }, this.lastPosition.tabName ); this.tabStructure.contentGeneratorPromises[this.tabStructure.activeTabId].then(() => { this.rememberLastPosition(containerEl); }); } hide() { this.statistics.destroy(); this.containerEl.empty(); } async tabFlashcards(containerEl) { containerEl.createEl("h3", { text: t("GROUP_TAGS_FOLDERS") }); new import_obsidian10.Setting(containerEl).setName(t("FLASHCARD_TAGS")).setDesc(t("FLASHCARD_TAGS_DESC")).addTextArea( (text) => text.setValue(this.plugin.data.settings.flashcardTags.join(" ")).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.flashcardTags = value.split(/\s+/); await this.plugin.savePluginData(); }); }) ); new import_obsidian10.Setting(containerEl).setName(t("CONVERT_FOLDERS_TO_DECKS")).setDesc(t("CONVERT_FOLDERS_TO_DECKS_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.convertFoldersToDecks).onChange(async (value) => { this.plugin.data.settings.convertFoldersToDecks = value; await this.plugin.savePluginData(); }) ); this.createSettingFoldersToIgnore(containerEl); containerEl.createEl("h3", { text: t("GROUP_FLASHCARD_REVIEW") }); new import_obsidian10.Setting(containerEl).setName(t("BURY_SIBLINGS_TILL_NEXT_DAY")).setDesc(t("BURY_SIBLINGS_TILL_NEXT_DAY_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.burySiblingCards).onChange(async (value) => { this.plugin.data.settings.burySiblingCards = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("REVIEW_CARD_ORDER_WITHIN_DECK")).addDropdown( (dropdown) => dropdown.addOptions({ NewFirstSequential: t("REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL"), DueFirstSequential: t("REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL"), NewFirstRandom: t("REVIEW_CARD_ORDER_NEW_FIRST_RANDOM"), DueFirstRandom: t("REVIEW_CARD_ORDER_DUE_FIRST_RANDOM"), EveryCardRandomDeckAndCard: t("REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD") }).setValue(this.plugin.data.settings.flashcardCardOrder).onChange(async (value) => { this.plugin.data.settings.flashcardCardOrder = value; await this.plugin.savePluginData(); this.display(); }) ); const deckOrderEnabled = this.plugin.data.settings.flashcardCardOrder != "EveryCardRandomDeckAndCard"; new import_obsidian10.Setting(containerEl).setName(t("REVIEW_DECK_ORDER")).addDropdown( (dropdown) => dropdown.addOptions( deckOrderEnabled ? { // eslint-disable-next-line camelcase PrevDeckComplete_Sequential: t( "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL" ), // eslint-disable-next-line camelcase PrevDeckComplete_Random: t( "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM" ) } : { EveryCardRandomDeckAndCard: t( "REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD" ) } ).setValue( deckOrderEnabled ? this.plugin.data.settings.flashcardDeckOrder : "EveryCardRandomDeckAndCard" ).setDisabled(!deckOrderEnabled).onChange(async (value) => { this.plugin.data.settings.flashcardDeckOrder = value; await this.plugin.savePluginData(); }) ); containerEl.createEl("h3", { text: t("GROUP_FLASHCARD_SEPARATORS") }); new import_obsidian10.Setting(containerEl).setName(t("CONVERT_HIGHLIGHTS_TO_CLOZES")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.convertHighlightsToClozes).onChange(async (value) => { const hightlightPattern = "==[123;;]answer[;;hint]=="; const clozePatternSet = new Set(this.plugin.data.settings.clozePatterns); if (value) { clozePatternSet.add(hightlightPattern); } else { clozePatternSet.delete(hightlightPattern); } this.plugin.data.settings.clozePatterns = [...clozePatternSet]; this.plugin.data.settings.convertHighlightsToClozes = value; await this.plugin.savePluginData(); this.display(); }) ); new import_obsidian10.Setting(containerEl).setName(t("CONVERT_BOLD_TEXT_TO_CLOZES")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.convertBoldTextToClozes).onChange(async (value) => { const boldPattern = "**[123;;]answer[;;hint]**"; const clozePatternSet = new Set(this.plugin.data.settings.clozePatterns); if (value) { clozePatternSet.add(boldPattern); } else { clozePatternSet.delete(boldPattern); } this.plugin.data.settings.clozePatterns = [...clozePatternSet]; this.plugin.data.settings.convertBoldTextToClozes = value; await this.plugin.savePluginData(); this.display(); }) ); new import_obsidian10.Setting(containerEl).setName(t("CONVERT_CURLY_BRACKETS_TO_CLOZES")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.convertCurlyBracketsToClozes).onChange(async (value) => { const curlyBracketsPattern = "{{[123;;]answer[;;hint]}}"; const clozePatternSet = new Set(this.plugin.data.settings.clozePatterns); if (value) { clozePatternSet.add(curlyBracketsPattern); } else { clozePatternSet.delete(curlyBracketsPattern); } this.plugin.data.settings.clozePatterns = [...clozePatternSet]; this.plugin.data.settings.convertCurlyBracketsToClozes = value; await this.plugin.savePluginData(); this.display(); }) ); const clozePatternsEl = new import_obsidian10.Setting(containerEl).setName(t("CLOZE_PATTERNS")); clozePatternsEl.descEl.insertAdjacentHTML( "beforeend", t("CLOZE_PATTERNS_DESC", { docsUrl: "https://www.stephenmwangi.com/obsidian-spaced-repetition/flashcards/cloze-cards/#cloze-types" }) ); clozePatternsEl.addTextArea( (text) => text.setPlaceholder( "Example:\n==[123;;]answer[;;hint]==\n**[123;;]answer[;;hint]**\n{{[123;;]answer[;;hint]}}" ).setValue(this.plugin.data.settings.clozePatterns.join("\n")).onChange((value) => { applySettingsUpdate(async () => { const hightlightPattern = "==[123;;]answer[;;hint]=="; const boldPattern = "**[123;;]answer[;;hint]**"; const curlyBracketsPattern = "{{[123;;]answer[;;hint]}}"; const clozePatternSet = new Set( value.split(/\n+/).map((v2) => v2.trim()).filter((v2) => v2) ); if (clozePatternSet.has(hightlightPattern)) { this.plugin.data.settings.convertHighlightsToClozes = true; } else { this.plugin.data.settings.convertHighlightsToClozes = false; } if (clozePatternSet.has(boldPattern)) { this.plugin.data.settings.convertBoldTextToClozes = true; } else { this.plugin.data.settings.convertBoldTextToClozes = false; } if (clozePatternSet.has(curlyBracketsPattern)) { this.plugin.data.settings.convertCurlyBracketsToClozes = true; } else { this.plugin.data.settings.convertCurlyBracketsToClozes = false; } this.plugin.data.settings.clozePatterns = [...clozePatternSet]; await this.plugin.savePluginData(); }); }) ); new import_obsidian10.Setting(containerEl).setName(t("INLINE_CARDS_SEPARATOR")).setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING")).addText( (text) => text.setValue(this.plugin.data.settings.singleLineCardSeparator).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.singleLineCardSeparator = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.singleLineCardSeparator = DEFAULT_SETTINGS.singleLineCardSeparator; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("INLINE_REVERSED_CARDS_SEPARATOR")).setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING")).addText( (text) => text.setValue(this.plugin.data.settings.singleLineReversedCardSeparator).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.singleLineReversedCardSeparator = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.singleLineReversedCardSeparator = DEFAULT_SETTINGS.singleLineReversedCardSeparator; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("MULTILINE_CARDS_SEPARATOR")).setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING")).addText( (text) => text.setValue(this.plugin.data.settings.multilineCardSeparator).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.multilineCardSeparator = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.multilineCardSeparator = DEFAULT_SETTINGS.multilineCardSeparator; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("MULTILINE_REVERSED_CARDS_SEPARATOR")).setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING")).addText( (text) => text.setValue(this.plugin.data.settings.multilineReversedCardSeparator).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.multilineReversedCardSeparator = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.multilineReversedCardSeparator = DEFAULT_SETTINGS.multilineReversedCardSeparator; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("MULTILINE_CARDS_END_MARKER")).setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING")).addText( (text) => text.setValue(this.plugin.data.settings.multilineCardEndMarker).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.multilineCardEndMarker = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.multilineCardEndMarker = DEFAULT_SETTINGS.multilineCardEndMarker; await this.plugin.savePluginData(); this.display(); }); }); } async tabNotes(containerEl) { containerEl.createEl("h3", { text: t("GROUP_TAGS_FOLDERS") }); new import_obsidian10.Setting(containerEl).setName(t("TAGS_TO_REVIEW")).setDesc(t("TAGS_TO_REVIEW_DESC")).addTextArea( (text) => text.setValue(this.plugin.data.settings.tagsToReview.join(" ")).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.tagsToReview = value.split(/\s+/); await this.plugin.savePluginData(); }); }) ); this.createSettingFoldersToIgnore(containerEl); containerEl.createEl("h3", { text: t("NOTES_REVIEW_QUEUE") }); new import_obsidian10.Setting(containerEl).setName(t("AUTO_NEXT_NOTE")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.autoNextNote).onChange(async (value) => { this.plugin.data.settings.autoNextNote = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("OPEN_RANDOM_NOTE")).setDesc(t("OPEN_RANDOM_NOTE_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.openRandomNote).onChange(async (value) => { this.plugin.data.settings.openRandomNote = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("REVIEW_PANE_ON_STARTUP")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.enableNoteReviewPaneOnStartup).onChange(async (value) => { this.plugin.data.settings.enableNoteReviewPaneOnStartup = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("MAX_N_DAYS_REVIEW_QUEUE")).addText( (text) => text.setValue(this.plugin.data.settings.maxNDaysNotesReviewQueue.toString()).onChange((value) => { applySettingsUpdate(async () => { const numValue = Number.parseInt(value); if (!isNaN(numValue)) { if (numValue < 1) { new import_obsidian10.Notice(t("MIN_ONE_DAY")); text.setValue( this.plugin.data.settings.maxNDaysNotesReviewQueue.toString() ); return; } this.plugin.data.settings.maxNDaysNotesReviewQueue = numValue; await this.plugin.savePluginData(); } else { new import_obsidian10.Notice(t("VALID_NUMBER_WARNING")); } }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.maxNDaysNotesReviewQueue = DEFAULT_SETTINGS.maxNDaysNotesReviewQueue; await this.plugin.savePluginData(); this.display(); }); }); } async createSettingFoldersToIgnore(containerEl) { new import_obsidian10.Setting(containerEl).setName(t("FOLDERS_TO_IGNORE")).setDesc(t("FOLDERS_TO_IGNORE_DESC")).addTextArea( (text) => text.setValue(this.plugin.data.settings.noteFoldersToIgnore.join("\n")).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.noteFoldersToIgnore = value.split(/\n+/).map((v2) => v2.trim()).filter((v2) => v2); await this.plugin.savePluginData(); this.display(); }); }) ); } async tabUiPreferences(containerEl) { containerEl.createEl("h3", { text: t("OBSIDIAN_INTEGRATION") }); new import_obsidian10.Setting(containerEl).setName(t("SHOW_RIBBON_ICON")).setDesc(t("SHOW_RIBBON_ICON_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showRibbonIcon).onChange(async (value) => { this.plugin.data.settings.showRibbonIcon = value; await this.plugin.savePluginData(); this.plugin.showRibbonIcon(value); }) ); new import_obsidian10.Setting(containerEl).setName(t("SHOW_STATUS_BAR")).setDesc(t("SHOW_STATUS_BAR_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showStatusBar).onChange(async (value) => { this.plugin.data.settings.showStatusBar = value; await this.plugin.savePluginData(); this.plugin.showStatusBar(value); }) ); new import_obsidian10.Setting(containerEl).setName(t("ENABLE_FILE_MENU_REVIEW_OPTIONS")).setDesc(t("ENABLE_FILE_MENU_REVIEW_OPTIONS_DESC")).addToggle( (toggle) => toggle.setValue(!this.plugin.data.settings.disableFileMenuReviewOptions).onChange(async (value) => { this.plugin.data.settings.disableFileMenuReviewOptions = !value; await this.plugin.savePluginData(); this.plugin.showFileMenuItems(value); }) ); containerEl.createEl("h3", { text: t("FLASHCARDS") }); new import_obsidian10.Setting(containerEl).setName(t("INITIALLY_EXPAND_SUBDECKS_IN_TREE")).setDesc(t("INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.initiallyExpandAllSubdecksInTree).onChange(async (value) => { this.plugin.data.settings.initiallyExpandAllSubdecksInTree = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("SHOW_CARD_CONTEXT")).setDesc(t("SHOW_CARD_CONTEXT_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showContextInCards).onChange(async (value) => { this.plugin.data.settings.showContextInCards = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("SHOW_INTERVAL_IN_REVIEW_BUTTONS")).setDesc(t("SHOW_INTERVAL_IN_REVIEW_BUTTONS_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showIntervalInReviewButtons).onChange(async (value) => { this.plugin.data.settings.showIntervalInReviewButtons = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("CARD_MODAL_HEIGHT_PERCENT")).setDesc(t("CARD_MODAL_SIZE_PERCENT_DESC")).addSlider( (slider) => slider.setLimits(10, 100, 5).setValue(this.plugin.data.settings.flashcardHeightPercentage).setDynamicTooltip().onChange(async (value) => { this.plugin.data.settings.flashcardHeightPercentage = value; await this.plugin.savePluginData(); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.flashcardHeightPercentage = DEFAULT_SETTINGS.flashcardHeightPercentage; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("CARD_MODAL_WIDTH_PERCENT")).setDesc(t("CARD_MODAL_SIZE_PERCENT_DESC")).addSlider( (slider) => slider.setLimits(10, 100, 5).setValue(this.plugin.data.settings.flashcardWidthPercentage).setDynamicTooltip().onChange(async (value) => { this.plugin.data.settings.flashcardWidthPercentage = value; await this.plugin.savePluginData(); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.flashcardWidthPercentage = DEFAULT_SETTINGS.flashcardWidthPercentage; await this.plugin.savePluginData(); this.display(); }); }); containerEl.createEl("h3", { text: t("GROUP_FLASHCARDS_NOTES") }); new import_obsidian10.Setting(containerEl).setName(t("FLASHCARD_EASY_LABEL")).setDesc(t("FLASHCARD_EASY_DESC")).addText( (text) => text.setValue(this.plugin.data.settings.flashcardEasyText).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.flashcardEasyText = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.flashcardEasyText = DEFAULT_SETTINGS.flashcardEasyText; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("FLASHCARD_GOOD_LABEL")).setDesc(t("FLASHCARD_GOOD_DESC")).addText( (text) => text.setValue(this.plugin.data.settings.flashcardGoodText).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.flashcardGoodText = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.flashcardGoodText = DEFAULT_SETTINGS.flashcardGoodText; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("FLASHCARD_HARD_LABEL")).setDesc(t("FLASHCARD_HARD_DESC")).addText( (text) => text.setValue(this.plugin.data.settings.flashcardHardText).onChange((value) => { applySettingsUpdate(async () => { this.plugin.data.settings.flashcardHardText = value; await this.plugin.savePluginData(); }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.flashcardHardText = DEFAULT_SETTINGS.flashcardHardText; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("REVIEW_BUTTON_DELAY")).setDesc(t("REVIEW_BUTTON_DELAY_DESC")).addSlider( (slider) => slider.setLimits(0, 5e3, 100).setValue(this.plugin.data.settings.reviewButtonDelay).setDynamicTooltip().onChange(async (value) => { this.plugin.data.settings.reviewButtonDelay = value; await this.plugin.savePluginData(); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.reviewButtonDelay = DEFAULT_SETTINGS.reviewButtonDelay; await this.plugin.savePluginData(); this.display(); }); }); } async tabScheduling(containerEl) { containerEl.createEl("h3", { text: t("ALGORITHM") }); const algoSettingEl = new import_obsidian10.Setting(containerEl).setName(t("ALGORITHM")); algoSettingEl.descEl.insertAdjacentHTML( "beforeend", t("CHECK_ALGORITHM_WIKI", { algoUrl: "https://www.stephenmwangi.com/obsidian-spaced-repetition/algorithms/" }) ); algoSettingEl.addDropdown( (dropdown) => dropdown.addOptions({ "SM-2-OSR": t("SM2_OSR_VARIANT") }).setValue(this.plugin.data.settings.algorithm).onChange(async (value) => { this.plugin.data.settings.algorithm = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("BASE_EASE")).setDesc(t("BASE_EASE_DESC")).addText( (text) => text.setValue(this.plugin.data.settings.baseEase.toString()).onChange((value) => { applySettingsUpdate(async () => { const numValue = Number.parseInt(value); if (!isNaN(numValue)) { if (numValue < 130) { new import_obsidian10.Notice(t("BASE_EASE_MIN_WARNING")); text.setValue(this.plugin.data.settings.baseEase.toString()); return; } this.plugin.data.settings.baseEase = numValue; await this.plugin.savePluginData(); } else { new import_obsidian10.Notice(t("VALID_NUMBER_WARNING")); } }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.baseEase = DEFAULT_SETTINGS.baseEase; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("LAPSE_INTERVAL_CHANGE")).setDesc(t("LAPSE_INTERVAL_CHANGE_DESC")).addSlider( (slider) => slider.setLimits(1, 99, 1).setValue(this.plugin.data.settings.lapsesIntervalChange * 100).setDynamicTooltip().onChange(async (value) => { this.plugin.data.settings.lapsesIntervalChange = value / 100; await this.plugin.savePluginData(); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.lapsesIntervalChange = DEFAULT_SETTINGS.lapsesIntervalChange; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("EASY_BONUS")).setDesc(t("EASY_BONUS_DESC")).addText( (text) => text.setValue((this.plugin.data.settings.easyBonus * 100).toString()).onChange((value) => { applySettingsUpdate(async () => { const numValue = Number.parseInt(value) / 100; if (!isNaN(numValue)) { if (numValue < 1) { new import_obsidian10.Notice(t("EASY_BONUS_MIN_WARNING")); text.setValue( (this.plugin.data.settings.easyBonus * 100).toString() ); return; } this.plugin.data.settings.easyBonus = numValue; await this.plugin.savePluginData(); } else { new import_obsidian10.Notice(t("VALID_NUMBER_WARNING")); } }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.easyBonus = DEFAULT_SETTINGS.easyBonus; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("LOAD_BALANCE")).setDesc(t("LOAD_BALANCE_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.loadBalance).onChange(async (value) => { this.plugin.data.settings.loadBalance = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("MAX_INTERVAL")).setDesc(t("MAX_INTERVAL_DESC")).addText( (text) => text.setValue(this.plugin.data.settings.maximumInterval.toString()).onChange((value) => { applySettingsUpdate(async () => { const numValue = Number.parseInt(value); if (!isNaN(numValue)) { if (numValue < 1) { new import_obsidian10.Notice(t("MAX_INTERVAL_MIN_WARNING")); text.setValue( this.plugin.data.settings.maximumInterval.toString() ); return; } this.plugin.data.settings.maximumInterval = numValue; await this.plugin.savePluginData(); } else { new import_obsidian10.Notice(t("VALID_NUMBER_WARNING")); } }); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.maximumInterval = DEFAULT_SETTINGS.maximumInterval; await this.plugin.savePluginData(); this.display(); }); }); new import_obsidian10.Setting(containerEl).setName(t("MAX_LINK_CONTRIB")).setDesc(t("MAX_LINK_CONTRIB_DESC")).addSlider( (slider) => slider.setLimits(0, 100, 1).setValue(this.plugin.data.settings.maxLinkFactor * 100).setDynamicTooltip().onChange(async (value) => { this.plugin.data.settings.maxLinkFactor = value / 100; await this.plugin.savePluginData(); }) ).addExtraButton((button) => { button.setIcon("reset").setTooltip(t("RESET_DEFAULT")).onClick(async () => { this.plugin.data.settings.maxLinkFactor = DEFAULT_SETTINGS.maxLinkFactor; await this.plugin.savePluginData(); this.display(); }); }); containerEl.createEl("h3", { text: t("GROUP_DATA_STORAGE") }); new import_obsidian10.Setting(containerEl).setName(t("GROUP_DATA_STORAGE")).setDesc(t("GROUP_DATA_STORAGE_DESC")).addDropdown( (dropdown) => dropdown.addOptions({ NOTES: t("STORE_IN_NOTES") }).setValue(this.plugin.data.settings.dataStore).onChange(async (value) => { this.plugin.data.settings.dataStore = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("INLINE_SCHEDULING_COMMENTS")).setDesc(t("INLINE_SCHEDULING_COMMENTS_DESC")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.cardCommentOnSameLine).onChange(async (value) => { this.plugin.data.settings.cardCommentOnSameLine = value; await this.plugin.savePluginData(); }) ); } async tabHelp(containerEl) { containerEl.createEl("h3", { text: `${t("HELP")}` }); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("CHECK_WIKI", { wikiUrl: "https://www.stephenmwangi.com/obsidian-spaced-repetition/" }) ); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("GITHUB_DISCUSSIONS", { discussionsUrl: "https://github.com/st3v3nmw/obsidian-spaced-repetition/discussions/" }) ); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("GITHUB_ISSUES", { issuesUrl: "https://github.com/st3v3nmw/obsidian-spaced-repetition/issues/" }) ); containerEl.createEl("h3", { text: `${t("LOGGING")}` }); new import_obsidian10.Setting(containerEl).setName(t("DISPLAY_SCHEDULING_DEBUG_INFO")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showSchedulingDebugMessages).onChange(async (value) => { this.plugin.data.settings.showSchedulingDebugMessages = value; await this.plugin.savePluginData(); }) ); new import_obsidian10.Setting(containerEl).setName(t("DISPLAY_PARSER_DEBUG_INFO")).addToggle( (toggle) => toggle.setValue(this.plugin.data.settings.showParserDebugMessages).onChange(async (value) => { this.plugin.data.settings.showParserDebugMessages = value; setDebugParser(this.plugin.data.settings.showParserDebugMessages); await this.plugin.savePluginData(); }) ); containerEl.createEl("h3", { text: t("GROUP_CONTRIBUTING") }); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("GITHUB_SOURCE_CODE", { githubProjectUrl: "https://github.com/st3v3nmw/obsidian-spaced-repetition" }) ); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("CODE_CONTRIBUTION_INFO", { codeContributionUrl: "https://www.stephenmwangi.com/obsidian-spaced-repetition/contributing/#code" }) ); containerEl.createEl("p").insertAdjacentHTML( "beforeend", t("TRANSLATION_CONTRIBUTION_INFO", { translationContributionUrl: "https://www.stephenmwangi.com/obsidian-spaced-repetition/contributing/#translating" }) ); } rememberLastPosition(containerElement) { const lastPosition = this.lastPosition; this.tabStructure.buttons[lastPosition.tabName].click(); containerElement.scrollTo({ top: this.lastPosition.scrollPosition, behavior: "auto" }); containerElement.addEventListener("scroll", (_2) => { this.lastPosition.scrollPosition = containerElement.scrollTop; }); for (const tabName in this.tabStructure.buttons) { const button = this.tabStructure.buttons[tabName]; button.onClickEvent((_2) => { lastPosition.tabName = tabName; }); } } }; // src/gui/sidebar.tsx var OsrSidebar = class { get app() { return this.plugin.app; } constructor(plugin, settings, nextNoteReviewHandler) { this.plugin = plugin; this.settings = settings; this.nextNoteReviewHandler = nextNoteReviewHandler; } redraw() { this.reviewQueueListView.redraw(); } getActiveLeaf(type) { const leaves = this.app.workspace.getLeavesOfType(type); if (leaves.length == 0) { return this.app.workspace.getRightLeaf(false); } return leaves[0]; } init() { this.plugin.registerView(REVIEW_QUEUE_VIEW_TYPE, (leaf) => { return this.reviewQueueListView = new ReviewQueueListView( leaf, this.nextNoteReviewHandler, this.settings ); }); } async activateReviewQueueViewPanel() { if (this.settings.enableNoteReviewPaneOnStartup) { await this.getActiveLeaf(REVIEW_QUEUE_VIEW_TYPE).setViewState({ type: REVIEW_QUEUE_VIEW_TYPE, active: true }); } } async openReviewQueueView() { const reviewQueueLeaf = this.getActiveLeaf(REVIEW_QUEUE_VIEW_TYPE); this.app.workspace.revealLeaf(reviewQueueLeaf); } }; // src/icons/app-icon.ts var import_obsidian11 = require("obsidian"); function appIcon() { (0, import_obsidian11.addIcon)( "SpacedRepIcon", ` ` ); } // src/next-note-review-handler.ts var import_obsidian13 = require("obsidian"); // src/gui/review-deck-selection-modal.tsx var import_obsidian12 = require("obsidian"); var ReviewDeckSelectionModal = class extends import_obsidian12.FuzzySuggestModal { constructor(app, deckKeys) { super(app); this.deckKeys = []; this.deckKeys = deckKeys; } getItems() { return this.deckKeys; } getItemText(item) { return item; } onChooseItem(deckKey, _2) { this.close(); this.submitCallback(deckKey); } }; // src/next-note-review-handler.ts var NextNoteReviewHandler = class { get lastSelectedReviewDeck() { return this._lastSelectedReviewDeck; } get noteReviewQueue() { return this._noteReviewQueue; } constructor(app, settings, noteReviewQueue) { this.app = app; this.settings = settings; this._noteReviewQueue = noteReviewQueue; } async autoReviewNextNote() { if (this.settings.autoNextNote) { if (!this._lastSelectedReviewDeck) { const reviewDeckKeys = this._noteReviewQueue.reviewDeckNameList; if (reviewDeckKeys.length > 0) this._lastSelectedReviewDeck = reviewDeckKeys[0]; else { new import_obsidian13.Notice(t("ALL_CAUGHT_UP")); return; } } this.reviewNextNote(this._lastSelectedReviewDeck); } } async reviewNextNoteModal() { const reviewDeckNames = this._noteReviewQueue.reviewDeckNameList; if (reviewDeckNames.length === 1) { this.reviewNextNote(reviewDeckNames[0]); } else { const deckSelectionModal = new ReviewDeckSelectionModal(this.app, reviewDeckNames); deckSelectionModal.submitCallback = (deckKey) => this.reviewNextNote(deckKey); deckSelectionModal.open(); } } async reviewNextNote(deckKey) { if (!this._noteReviewQueue.reviewDeckNameList.contains(deckKey)) { new import_obsidian13.Notice(t("NO_DECK_EXISTS", { deckName: deckKey })); return; } this._lastSelectedReviewDeck = deckKey; const deck = this._noteReviewQueue.reviewDecks.get(deckKey); const notefile = deck.determineNextNote(this.settings.openRandomNote); if (notefile) { await this.openNote(deckKey, notefile.tfile); } else { new import_obsidian13.Notice(t("ALL_CAUGHT_UP")); } } async openNote(deckName, file) { this._lastSelectedReviewDeck = deckName; await this.app.workspace.getLeaf().openFile(file); } }; // src/note-review-deck.ts var SchedNote = class { constructor(note, dueUnix) { this.note = note; this.dueUnix = dueUnix; } isDue(todayUnix) { return this.dueUnix <= todayUnix; } }; var NoteReviewDeck = class { constructor(name) { this._newNotes = []; this._scheduledNotes = []; this._dueNotesCount = 0; this._deckName = name; this._activeFolders = /* @__PURE__ */ new Set([this._deckName, t("TODAY")]); } get deckName() { return this._deckName; } get newNotes() { return this._newNotes; } get scheduledNotes() { return this._scheduledNotes; } get dueNotesCount() { return this._dueNotesCount; } get activeFolders() { return this._activeFolders; } calcDueNotesCount(todayUnix) { this._dueNotesCount = 0; this.scheduledNotes.forEach((scheduledNote) => { if (scheduledNote.isDue(todayUnix)) { this._dueNotesCount++; } }); } sortNotesByDateAndImportance(pageranks) { this._newNotes = this.newNotes.sort( (a2, b2) => (pageranks[b2.path] || 0) - (pageranks[a2.path] || 0) ); this._scheduledNotes = this.scheduledNotes.sort((a2, b2) => { const result = a2.dueUnix - b2.dueUnix; if (result != 0) { return result; } return (pageranks[b2.note.path] || 0) - (pageranks[a2.note.path] || 0); }); } determineNextNote(openRandomNote) { const todayUnix = globalDateProvider.today.valueOf(); const dueNotes = this.scheduledNotes.filter((note) => note.isDue(todayUnix)); if (dueNotes.length > 0) { const index = openRandomNote ? globalRandomNumberProvider.getInteger(0, dueNotes.length - 1) : 0; return dueNotes[index].note; } if (this.newNotes.length > 0) { const index = openRandomNote ? globalRandomNumberProvider.getInteger(0, this.newNotes.length - 1) : 0; return this.newNotes[index]; } return null; } }; // src/note-review-queue.ts var NoteReviewQueue = class { get reviewDecks() { return this._reviewDecks; } get dueNotesCount() { return this._dueNotesCount; } get reviewDeckNameList() { return [...this._reviewDecks.keys()]; } init() { this._reviewDecks = /* @__PURE__ */ new Map(); } calcDueNotesCount(todayUnix) { this._dueNotesCount = 0; this._reviewDecks.forEach((reviewDeck) => { reviewDeck.calcDueNotesCount(todayUnix); this._dueNotesCount += reviewDeck.dueNotesCount; }); } addNoteToQueue(noteFile, noteSchedule, matchedNoteTags) { for (const matchedNoteTag of matchedNoteTags) { if (!this.reviewDecks.has(matchedNoteTag)) { this.reviewDecks.set(matchedNoteTag, new NoteReviewDeck(matchedNoteTag)); } } if (noteSchedule == null) { for (const matchedNoteTag of matchedNoteTags) { this.reviewDecks.get(matchedNoteTag).newNotes.push(noteFile); } } else { for (const matchedNoteTag of matchedNoteTags) { this.reviewDecks.get(matchedNoteTag).scheduledNotes.push(new SchedNote(noteFile, noteSchedule.dueDateAsUnix)); } } } updateScheduleInfo(note, scheduleInfo) { this.reviewDecks.forEach((reviewDeck) => { let wasDueInDeck = false; for (const scheduledNote of reviewDeck.scheduledNotes) { if (scheduledNote.note.path === note.path) { scheduledNote.dueUnix = scheduleInfo.dueDate.valueOf(); wasDueInDeck = true; break; } } if (!wasDueInDeck) { reviewDeck.newNotes.splice( reviewDeck.newNotes.findIndex((newNote) => newNote.path === note.path), 1 ); reviewDeck.scheduledNotes.push(new SchedNote(note, scheduleInfo.dueDate.valueOf())); } }); } }; // src/plugin-data.ts var DEFAULT_DATA = { settings: DEFAULT_SETTINGS, buryDate: "", buryList: [], historyDeck: null }; // src/question-postponement-list.ts var QuestionPostponementList = class { constructor(plugin, settings, list) { this.plugin = plugin; this.settings = settings; this.list = list; } async clearIfNewDay(data) { const now2 = window.moment(Date.now()); const todayDate = now2.format("YYYY-MM-DD"); const isNewDay = todayDate !== data.buryDate; if (isNewDay) { data.buryDate = todayDate; this.clear(); await this.write(); } } clear() { this.list.splice(0); } add(question) { if (!this.includes(question)) this.list.push(question.questionText.textHash); } includes(question) { return this.list.includes(question.questionText.textHash); } async write() { if (this.plugin == null) return; await this.plugin.savePluginData(); } }; // src/main.ts var SRPlugin = class _SRPlugin extends import_obsidian14.Plugin { constructor() { super(...arguments); this.ribbonIcon = null; this.statusBar = null; } async onload() { await this.loadPluginData(); const noteReviewQueue = new NoteReviewQueue(); this.nextNoteReviewHandler = new NextNoteReviewHandler( this.app, this.data.settings, noteReviewQueue ); this.osrSidebar = new OsrSidebar(this, this.data.settings, this.nextNoteReviewHandler); this.osrSidebar.init(); this.app.workspace.onLayoutReady(async () => { await this.osrSidebar.activateReviewQueueViewPanel(); setTimeout(async () => { if (!this.osrAppCore.syncLock) { await this.sync(); } }, 2e3); }); const questionPostponementList = new QuestionPostponementList( this, this.data.settings, this.data.buryList ); const osrNoteLinkInfoFinder = new ObsidianVaultNoteLinkInfoFinder(this.app.metadataCache); this.osrAppCore = new OsrAppCore(this.app); this.osrAppCore.init( questionPostponementList, osrNoteLinkInfoFinder, this.data.settings, this.onOsrVaultDataChanged.bind(this), noteReviewQueue ); appIcon(); this.showStatusBar(this.data.settings.showStatusBar); this.showRibbonIcon(this.data.settings.showRibbonIcon); this.showFileMenuItems(!this.data.settings.disableFileMenuReviewOptions); this.addPluginCommands(); this.addSettingTab(new SRSettingTab(this.app, this)); } showFileMenuItems(status) { if (this.fileMenuHandler === void 0) { this.fileMenuHandler = (menu, fileish) => { if (fileish instanceof import_obsidian14.TFile && fileish.extension === "md") { menu.addItem((item) => { item.setTitle( t("REVIEW_DIFFICULTY_FILE_MENU", { difficulty: this.data.settings.flashcardEasyText }) ).setIcon("SpacedRepIcon").onClick(() => { this.saveNoteReviewResponse(fileish, 0 /* Easy */); }); }); menu.addItem((item) => { item.setTitle( t("REVIEW_DIFFICULTY_FILE_MENU", { difficulty: this.data.settings.flashcardGoodText }) ).setIcon("SpacedRepIcon").onClick(() => { this.saveNoteReviewResponse(fileish, 1 /* Good */); }); }); menu.addItem((item) => { item.setTitle( t("REVIEW_DIFFICULTY_FILE_MENU", { difficulty: this.data.settings.flashcardHardText }) ).setIcon("SpacedRepIcon").onClick(() => { this.saveNoteReviewResponse(fileish, 2 /* Hard */); }); }); } }; } if (status) { this.registerEvent(this.app.workspace.on("file-menu", this.fileMenuHandler)); } else { this.app.workspace.off("file-menu", this.fileMenuHandler); } } addPluginCommands() { this.addCommand({ id: "srs-note-review-open-note", name: t("OPEN_NOTE_FOR_REVIEW"), callback: async () => { if (!this.osrAppCore.syncLock) { await this.sync(); this.nextNoteReviewHandler.reviewNextNoteModal(); } } }); this.addCommand({ id: "srs-note-review-easy", name: t("REVIEW_NOTE_DIFFICULTY_CMD", { difficulty: this.data.settings.flashcardEasyText }), callback: () => { const openFile = this.app.workspace.getActiveFile(); if (openFile && openFile.extension === "md") { this.saveNoteReviewResponse(openFile, 0 /* Easy */); } } }); this.addCommand({ id: "srs-note-review-good", name: t("REVIEW_NOTE_DIFFICULTY_CMD", { difficulty: this.data.settings.flashcardGoodText }), callback: () => { const openFile = this.app.workspace.getActiveFile(); if (openFile && openFile.extension === "md") { this.saveNoteReviewResponse(openFile, 1 /* Good */); } } }); this.addCommand({ id: "srs-note-review-hard", name: t("REVIEW_NOTE_DIFFICULTY_CMD", { difficulty: this.data.settings.flashcardHardText }), callback: () => { const openFile = this.app.workspace.getActiveFile(); if (openFile && openFile.extension === "md") { this.saveNoteReviewResponse(openFile, 2 /* Hard */); } } }); this.addCommand({ id: "srs-review-flashcards", name: t("REVIEW_ALL_CARDS"), callback: async () => { if (!this.osrAppCore.syncLock) { await this.sync(); this.openFlashcardModal( this.osrAppCore.reviewableDeckTree, this.osrAppCore.remainingDeckTree, 1 /* Review */ ); } } }); this.addCommand({ id: "srs-cram-flashcards", name: t("CRAM_ALL_CARDS"), callback: async () => { await this.sync(); this.openFlashcardModal( this.osrAppCore.reviewableDeckTree, this.osrAppCore.reviewableDeckTree, 0 /* Cram */ ); } }); this.addCommand({ id: "srs-review-flashcards-in-note", name: t("REVIEW_CARDS_IN_NOTE"), callback: async () => { const openFile = this.app.workspace.getActiveFile(); if (openFile && openFile.extension === "md") { this.openFlashcardModalForSingleNote(openFile, 1 /* Review */); } } }); this.addCommand({ id: "srs-cram-flashcards-in-note", name: t("CRAM_CARDS_IN_NOTE"), callback: async () => { const openFile = this.app.workspace.getActiveFile(); if (openFile && openFile.extension === "md") { this.openFlashcardModalForSingleNote(openFile, 0 /* Cram */); } } }); this.addCommand({ id: "srs-open-review-queue-view", name: t("OPEN_REVIEW_QUEUE_VIEW"), callback: async () => { await this.osrSidebar.openReviewQueueView(); } }); } onunload() { this.app.workspace.getLeavesOfType(REVIEW_QUEUE_VIEW_TYPE).forEach((leaf) => leaf.detach()); } async openFlashcardModalForSingleNote(noteFile, reviewMode) { const note = await this.loadNote(noteFile); const deckTree = new Deck2("root", null); note.appendCardsToDeck(deckTree); const remainingDeckTree = DeckTreeFilter.filterForRemainingCards( this.osrAppCore.questionPostponementList, deckTree, reviewMode ); this.openFlashcardModal(deckTree, remainingDeckTree, reviewMode); } openFlashcardModal(fullDeckTree, remainingDeckTree, reviewMode) { const deckIterator = _SRPlugin.createDeckTreeIterator(this.data.settings); const reviewSequencer = new FlashcardReviewSequencer( reviewMode, deckIterator, this.data.settings, SrsAlgorithm.getInstance(), this.osrAppCore.questionPostponementList, this.osrAppCore.dueDateFlashcardHistogram ); reviewSequencer.setDeckTree(fullDeckTree, remainingDeckTree); new FlashcardModal(this.app, this, this.data.settings, reviewSequencer, reviewMode).open(); } static createDeckTreeIterator(settings) { let cardOrder = CardOrder[settings.flashcardCardOrder]; if (cardOrder === void 0) cardOrder = 2 /* DueFirstSequential */; let deckOrder = DeckOrder[settings.flashcardDeckOrder]; if (deckOrder === void 0) deckOrder = 0 /* PrevDeckComplete_Sequential */; const iteratorOrder = { deckOrder, cardOrder }; return new DeckTreeIterator(iteratorOrder, null); } async sync() { if (this.osrAppCore.syncLock) { return; } const now2 = window.moment(Date.now()); this.osrAppCore.defaultTextDirection = this.getObsidianRtlSetting(); await this.osrAppCore.loadVault(); if (this.data.settings.showSchedulingDebugMessages) { console.log(`SR: ${t("DECKS")}`, this.osrAppCore.reviewableDeckTree); console.log( "SR: " + t("SYNC_TIME_TAKEN", { t: Date.now() - now2.valueOf() }) ); } } onOsrVaultDataChanged() { this.statusBar.setText( t("STATUS_BAR", { dueNotesCount: this.osrAppCore.noteReviewQueue.dueNotesCount, dueFlashcardsCount: this.osrAppCore.remainingDeckTree.getCardCount( 2 /* All */, true ) }) ); if (this.data.settings.enableNoteReviewPaneOnStartup) this.osrSidebar.redraw(); } async loadNote(noteFile) { const loader = new NoteFileLoader(this.data.settings); const srFile = this.createSrTFile(noteFile); const folderTopicPath = TopicPath.getFolderPathFromFilename( srFile, this.data.settings ); const note = await loader.load( this.createSrTFile(noteFile), this.getObsidianRtlSetting(), folderTopicPath ); if (note.hasChanged) { note.writeNoteFile(this.data.settings); } return note; } getObsidianRtlSetting() { const v2 = this.app.vault.getConfig("rightToLeft"); return convertToStringOrEmpty(v2) == "true" ? 2 /* Rtl */ : 1 /* Ltr */; } async saveNoteReviewResponse(note, response) { const noteSrTFile = this.createSrTFile(note); if (SettingsUtil.isPathInNoteIgnoreFolder(this.data.settings, note.path)) { new import_obsidian14.Notice(t("NOTE_IN_IGNORED_FOLDER")); return; } const tags = noteSrTFile.getAllTagsFromCache(); if (!SettingsUtil.isAnyTagANoteReviewTag(this.data.settings, tags)) { new import_obsidian14.Notice(t("PLEASE_TAG_NOTE")); return; } await this.osrAppCore.saveNoteReviewResponse(noteSrTFile, response, this.data.settings); new import_obsidian14.Notice(t("RESPONSE_RECEIVED")); if (this.data.settings.autoNextNote) { this.nextNoteReviewHandler.autoReviewNextNote(); } } createSrTFile(note) { return new SrTFile(this.app.vault, this.app.metadataCache, note); } async loadPluginData() { const loadedData = await this.loadData(); if (loadedData == null ? void 0 : loadedData.settings) upgradeSettings(loadedData.settings); this.data = Object.assign({}, DEFAULT_DATA, loadedData); this.data.settings = Object.assign({}, DEFAULT_SETTINGS, this.data.settings); setDebugParser(this.data.settings.showParserDebugMessages); this.setupDataStoreAndAlgorithmInstances(this.data.settings); } setupDataStoreAndAlgorithmInstances(settings) { DataStore.instance = new StoreInNotes(settings); SrsAlgorithm.instance = new SrsAlgorithmOsr(settings); DataStoreAlgorithm.instance = new DataStoreInNoteAlgorithmOsr(settings); } async savePluginData() { await this.saveData(this.data); } showRibbonIcon(status) { if (!this.ribbonIcon) { this.ribbonIcon = this.addRibbonIcon("SpacedRepIcon", t("REVIEW_CARDS"), async () => { if (!this.osrAppCore.syncLock) { await this.sync(); this.openFlashcardModal( this.osrAppCore.reviewableDeckTree, this.osrAppCore.remainingDeckTree, 1 /* Review */ ); } }); } if (status) { this.ribbonIcon.style.display = ""; } else { this.ribbonIcon.style.display = "none"; } } showStatusBar(status) { if (!this.statusBar) { this.statusBar = this.addStatusBarItem(); this.statusBar.classList.add("mod-clickable"); this.statusBar.setAttribute("aria-label", t("OPEN_NOTE_FOR_REVIEW")); this.statusBar.setAttribute("aria-label-position", "top"); this.statusBar.addEventListener("click", async () => { if (!this.osrAppCore.syncLock) { await this.sync(); this.nextNoteReviewHandler.reviewNextNoteModal(); } }); } if (status) { this.statusBar.style.display = ""; } else { this.statusBar.style.display = "none"; } } }; /*! Bundled license information: moment/moment.js: (*! moment.js *) (*! version : 2.30.1 *) (*! authors : Tim Wood, Iskren Chernev, Moment.js contributors *) (*! license : MIT *) (*! momentjs.com *) @kurkle/color/dist/color.esm.js: (*! * @kurkle/color v0.3.2 * https://github.com/kurkle/color#readme * (c) 2023 Jukka Kurkela * Released under the MIT License *) chart.js/dist/chunks/helpers.segment.js: (*! * Chart.js v4.4.4 * https://www.chartjs.org * (c) 2024 Chart.js Contributors * Released under the MIT License *) chart.js/dist/chart.js: (*! * Chart.js v4.4.4 * https://www.chartjs.org * (c) 2024 Chart.js Contributors * Released under the MIT License *) */ /* nosourcemap */