您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
批量下载 Iwara 视频
// ==UserScript== // @name Iwara Download Tool // @description Download videos from iwara.tv // @name:ja Iwara バッチダウンローダー // @description:ja Iwara 動画バッチをダウンロード // @name:zh-CN Iwara 批量下载工具 // @description:zh-CN 批量下载 Iwara 视频 // @icon https://www.google.com/s2/favicons?sz=64&domain=iwara.tv // @namespace https://github.com/dawn-lc/ // @author dawn-lc // @license Apache-2.0 // @copyright 2025, Dawnlc (https://dawnlc.me/) // @source https://github.com/dawn-lc/IwaraDownloadTool // @supportURL https://github.com/dawn-lc/IwaraDownloadTool/issues // @connect iwara.tv // @connect *.iwara.* // @connect mmdfans.net // @connect *.mmdfans.net // @connect localhost // @connect 127.0.0.1 // @connect * // @include *://*.iwara.*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_listValues // @grant GM_deleteValue // @grant GM_addValueChangeListener // @grant GM_addStyle // @grant GM_setClipboard // @grant GM_download // @grant GM_xmlhttpRequest // @grant GM_openInTab // @grant GM_getTab // @grant GM_saveTab // @grant GM_getTabs // @grant GM_info // @grant unsafeWindow // @grant window.close // @run-at document-start // @version 3.3.50 // ==/UserScript== "use strict"; (() => { 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 __require = ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __commonJS = (cb, mod) => function __require2() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var require_moment = __commonJS({ "node_modules/moment/moment.js"(exports, module) { "use strict"; ; (function(global2, factory) { typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global2.moment = factory(); })(exports, function() { "use strict"; var hookCallback; function hooks() { return hookCallback.apply(null, arguments); } function setHookCallback(callback) { hookCallback = callback; } function isArray3(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(a, b) { return Object.prototype.hasOwnProperty.call(a, b); } 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 isUndefined2(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 map(arr, fn) { var res = [], i, arrLen = arr.length; for (i = 0; i < arrLen; ++i) { res.push(fn(arr[i], i)); } return res; } function extend2(a, b) { for (var i in b) { if (hasOwnProp(b, i)) { a[i] = b[i]; } } if (hasOwnProp(b, "toString")) { a.toString = b.toString; } if (hasOwnProp(b, "valueOf")) { a.valueOf = b.valueOf; } return a; } function createUTC(input, format2, locale2, strict) { return createLocalOrUTC(input, format2, locale2, 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(m) { if (m._pf == null) { m._pf = defaultParsingFlags(); } return m._pf; } var some; if (Array.prototype.some) { some = Array.prototype.some; } else { some = function(fun) { var t = Object(this), len = t.length >>> 0, i; for (i = 0; i < len; i++) { if (i in t && fun.call(this, t[i], i, t)) { return true; } } return false; }; } function isValid(m) { var flags = null, parsedParts = false, isNowValid = m._d && !isNaN(m._d.getTime()); if (isNowValid) { flags = getParsingFlags(m); parsedParts = some.call(flags.parsedDateParts, function(i) { return i != 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 (m._strict) { isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === void 0; } } if (Object.isFrozen == null || !Object.isFrozen(m)) { m._isValid = isNowValid; } else { return isNowValid; } return m._isValid; } function createInvalid(flags) { var m = createUTC(NaN); if (flags != null) { extend2(getParsingFlags(m), flags); } else { getParsingFlags(m).userInvalidated = true; } return m; } var momentProperties = hooks.momentProperties = [], updateInProgress = false; function copyConfig(to2, from2) { var i, prop, val, momentPropertiesLen = momentProperties.length; if (!isUndefined2(from2._isAMomentObject)) { to2._isAMomentObject = from2._isAMomentObject; } if (!isUndefined2(from2._i)) { to2._i = from2._i; } if (!isUndefined2(from2._f)) { to2._f = from2._f; } if (!isUndefined2(from2._l)) { to2._l = from2._l; } if (!isUndefined2(from2._strict)) { to2._strict = from2._strict; } if (!isUndefined2(from2._tzm)) { to2._tzm = from2._tzm; } if (!isUndefined2(from2._isUTC)) { to2._isUTC = from2._isUTC; } if (!isUndefined2(from2._offset)) { to2._offset = from2._offset; } if (!isUndefined2(from2._pf)) { to2._pf = getParsingFlags(from2); } if (!isUndefined2(from2._locale)) { to2._locale = from2._locale; } if (momentPropertiesLen > 0) { for (i = 0; i < momentPropertiesLen; i++) { prop = momentProperties[i]; val = from2[prop]; if (!isUndefined2(val)) { to2[prop] = val; } } } return to2; } function Moment2(config2) { copyConfig(this, config2); this._d = new Date(config2._d != null ? config2._d.getTime() : NaN); if (!this.isValid()) { this._d = new Date(NaN); } if (updateInProgress === false) { updateInProgress = true; hooks.updateOffset(this); updateInProgress = false; } } function isMoment(obj) { return obj instanceof Moment2 || 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, fn) { var firstTime = true; return extend2(function() { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(null, msg); } if (firstTime) { var args = [], arg, i, key, argLen = arguments.length; for (i = 0; i < argLen; i++) { arg = ""; if (typeof arguments[i] === "object") { arg += "\n[" + i + "] "; for (key in arguments[0]) { if (hasOwnProp(arguments[0], key)) { arg += key + ": " + arguments[0][key] + ", "; } } arg = arg.slice(0, -2); } else { arg = arguments[i]; } args.push(arg); } warn(msg + "\nArguments: " + Array.prototype.slice.call(args).join("") + "\n" + new Error().stack); firstTime = false; } return fn.apply(this, arguments); }, fn); } 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 isFunction(input) { return typeof Function !== "undefined" && input instanceof Function || Object.prototype.toString.call(input) === "[object Function]"; } function set(config2) { var prop, i; for (i in config2) { if (hasOwnProp(config2, i)) { prop = config2[i]; if (isFunction(prop)) { this[i] = prop; } else { this["_" + i] = prop; } } } this._config = config2; this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + "|" + /\d{1,2}/.source); } function mergeConfigs(parentConfig, childConfig) { var res = extend2({}, parentConfig), prop; for (prop in childConfig) { if (hasOwnProp(childConfig, prop)) { if (isObject2(parentConfig[prop]) && isObject2(childConfig[prop])) { res[prop] = {}; extend2(res[prop], parentConfig[prop]); extend2(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] = extend2({}, res[prop]); } } return res; } function Locale(config2) { if (config2 != null) { this.set(config2); } } var keys2; if (Object.keys) { keys2 = Object.keys; } else { keys2 = function(obj) { var i, res = []; for (i in obj) { if (hasOwnProp(obj, i)) { res.push(i); } } 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, now2) { var output = this._calendar[key] || this._calendar["sameElse"]; return isFunction(output) ? output.call(mom, now2) : output; } function zeroFill(number, targetLength, forceSign) { var absNumber = "" + Math.abs(number), zerosToFill = targetLength - absNumber.length, sign2 = number >= 0; return (sign2 ? 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, callback) { var func = callback; if (typeof callback === "string") { func = function() { return this[callback](); }; } 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), i, length; for (i = 0, length = array.length; i < length; i++) { if (formatTokenFunctions[array[i]]) { array[i] = formatTokenFunctions[array[i]]; } else { array[i] = removeFormattingTokens(array[i]); } } return function(mom) { var output = "", i2; for (i2 = 0; i2 < length; i2++) { output += isFunction(array[i2]) ? array[i2].call(mom, format2) : array[i2]; } return output; }; } function formatMoment(m, format2) { if (!m.isValid()) { return m.localeData().invalidDate(); } format2 = expandFormat(format2, m.localeData()); formatFunctions[format2] = formatFunctions[format2] || makeFormatFunction(format2); return formatFunctions[format2](m); } function expandFormat(format2, locale2) { var i = 5; function replaceLongDateFormatTokens(input) { return locale2.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; while (i >= 0 && localFormattingTokens.test(format2)) { format2 = format2.replace(localFormattingTokens, replaceLongDateFormatTokens); localFormattingTokens.lastIndex = 0; i -= 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 isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); } function pastFuture(diff2, output) { var format2 = this._relativeTime[diff2 > 0 ? "future" : "past"]; return isFunction(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 = [], u; for (u in unitsObj) { if (hasOwnProp(unitsObj, u)) { units.push({ unit: u, priority: priorities[u] }); } } units.sort(function(a, b) { return a.priority - b.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] = isFunction(regex) ? regex : function(isStrict, localeData2) { return isStrict && strictRegex ? strictRegex : regex; }; } function getParseRegexForToken(token2, config2) { if (!hasOwnProp(regexes, token2)) { return new RegExp(unescapeFormat(token2)); } return regexes[token2](config2._strict, config2._locale); } function unescapeFormat(s) { return regexEscape(s.replace("\\", "").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(matched, p1, p2, p3, p4) { return p1 || p2 || p3 || p4; })); } function regexEscape(s) { return s.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, callback) { var i, func = callback, tokenLen; if (typeof token2 === "string") { token2 = [token2]; } if (isNumber2(callback)) { func = function(input, array) { array[callback] = toInt(input); }; } tokenLen = token2.length; for (i = 0; i < tokenLen; i++) { tokens[token2[i]] = func; } } function addWeekParseToken(token2, callback) { addParseToken(token2, function(input, array, config2, token3) { config2._w = config2._w || {}; callback(input, config2._w, config2, token3); }); } function addTimeToArrayFromToken(token2, input, config2) { if (input != null && hasOwnProp(tokens, token2)) { tokens[token2](input, config2._a, config2, 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 y = this.year(); return y <= 9999 ? zeroFill(y, 4) : "+" + y; }); 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 d = mom._d, isUTC = mom._isUTC; switch (unit) { case "Milliseconds": return isUTC ? d.getUTCMilliseconds() : d.getMilliseconds(); case "Seconds": return isUTC ? d.getUTCSeconds() : d.getSeconds(); case "Minutes": return isUTC ? d.getUTCMinutes() : d.getMinutes(); case "Hours": return isUTC ? d.getUTCHours() : d.getHours(); case "Date": return isUTC ? d.getUTCDate() : d.getDate(); case "Day": return isUTC ? d.getUTCDay() : d.getDay(); case "Month": return isUTC ? d.getUTCMonth() : d.getMonth(); case "FullYear": return isUTC ? d.getUTCFullYear() : d.getFullYear(); default: return NaN; } } function set$1(mom, unit, value) { var d, isUTC, year, month, date; if (!mom.isValid() || isNaN(value)) { return; } d = mom._d; isUTC = mom._isUTC; switch (unit) { case "Milliseconds": return void (isUTC ? d.setUTCMilliseconds(value) : d.setMilliseconds(value)); case "Seconds": return void (isUTC ? d.setUTCSeconds(value) : d.setSeconds(value)); case "Minutes": return void (isUTC ? d.setUTCMinutes(value) : d.setMinutes(value)); case "Hours": return void (isUTC ? d.setUTCHours(value) : d.setHours(value)); case "Date": return void (isUTC ? d.setUTCDate(value) : d.setDate(value)); case "FullYear": break; default: return; } year = value; month = mom.month(); date = mom.date(); date = date === 29 && month === 1 && !isLeapYear(year) ? 28 : date; void (isUTC ? d.setUTCFullYear(year, month, date) : d.setFullYear(year, month, date)); } function stringGet(units) { units = normalizeUnits(units); if (isFunction(this[units])) { return this[units](); } return this; } function stringSet(units, value) { if (typeof units === "object") { units = normalizeObjectUnits(units); var prioritized = getPrioritizedUnits(units), i, prioritizedLen = prioritized.length; for (i = 0; i < prioritizedLen; i++) { this[prioritized[i].unit](units[prioritized[i].unit]); } } else { units = normalizeUnits(units); if (isFunction(this[units])) { return this[units](value); } } return this; } function mod(n, x) { return (n % x + x) % x; } var indexOf; if (Array.prototype.indexOf) { indexOf = Array.prototype.indexOf; } else { indexOf = function(o) { var i; for (i = 0; i < this.length; ++i) { if (this[i] === o) { return i; } } 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, locale2) { return locale2.monthsShortRegex(isStrict); }); addRegexToken("MMMM", function(isStrict, locale2) { return locale2.monthsRegex(isStrict); }); addParseToken(["M", "MM"], function(input, array) { array[MONTH] = toInt(input) - 1; }); addParseToken(["MMM", "MMMM"], function(input, array, config2, token2) { var month = config2._locale.monthsParse(input, token2, config2._strict); if (month != null) { array[MONTH] = month; } else { getParsingFlags(config2).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(m, format2) { if (!m) { return isArray3(this._months) ? this._months : this._months["standalone"]; } return isArray3(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format2) ? "format" : "standalone"][m.month()]; } function localeMonthsShort(m, format2) { if (!m) { return isArray3(this._monthsShort) ? this._monthsShort : this._monthsShort["standalone"]; } return isArray3(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format2) ? "format" : "standalone"][m.month()]; } function handleStrictParse(monthName, format2, strict) { var i, ii, mom, llc = monthName.toLocaleLowerCase(); if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; for (i = 0; i < 12; ++i) { mom = createUTC([2e3, i]); this._shortMonthsParse[i] = this.monthsShort(mom, "").toLocaleLowerCase(); this._longMonthsParse[i] = 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 i, mom, regex; if (this._monthsParseExact) { return handleStrictParse.call(this, monthName, format2, strict); } if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; } for (i = 0; i < 12; i++) { mom = createUTC([2e3, i]); if (strict && !this._longMonthsParse[i]) { this._longMonthsParse[i] = new RegExp("^" + this.months(mom, "").replace(".", "") + "$", "i"); this._shortMonthsParse[i] = new RegExp("^" + this.monthsShort(mom, "").replace(".", "") + "$", "i"); } if (!strict && !this._monthsParse[i]) { regex = "^" + this.months(mom, "") + "|^" + this.monthsShort(mom, ""); this._monthsParse[i] = new RegExp(regex.replace(".", ""), "i"); } if (strict && format2 === "MMMM" && this._longMonthsParse[i].test(monthName)) { return i; } else if (strict && format2 === "MMM" && this._shortMonthsParse[i].test(monthName)) { return i; } else if (!strict && this._monthsParse[i].test(monthName)) { return i; } } } 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(a, b) { return b.length - a.length; } var shortPieces = [], longPieces = [], mixedPieces = [], i, mom, shortP, longP; for (i = 0; i < 12; i++) { mom = createUTC([2e3, i]); 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(y, m, d, h, M, s, ms) { var date; if (y < 100 && y >= 0) { date = new Date(y + 400, m, d, h, M, s, ms); if (isFinite(date.getFullYear())) { date.setFullYear(y); } } else { date = new Date(y, m, d, h, M, s, ms); } return date; } function createUTCDate(y) { var date, args; if (y < 100 && y >= 0) { args = Array.prototype.slice.call(arguments); args[0] = y + 400; date = new Date(Date.UTC.apply(null, args)); if (isFinite(date.getUTCFullYear())) { date.setUTCFullYear(y); } } 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, config2, 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, doy: 6 }; 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, locale2) { return locale2.weekdaysMinRegex(isStrict); }); addRegexToken("ddd", function(isStrict, locale2) { return locale2.weekdaysShortRegex(isStrict); }); addRegexToken("dddd", function(isStrict, locale2) { return locale2.weekdaysRegex(isStrict); }); addWeekParseToken(["dd", "ddd", "dddd"], function(input, week, config2, token2) { var weekday = config2._locale.weekdaysParse(input, token2, config2._strict); if (weekday != null) { week.d = weekday; } else { getParsingFlags(config2).invalidWeekday = input; } }); addWeekParseToken(["d", "e", "E"], function(input, week, config2, token2) { week[token2] = toInt(input); }); function parseWeekday(input, locale2) { if (typeof input !== "string") { return input; } if (!isNaN(input)) { return parseInt(input, 10); } input = locale2.weekdaysParse(input); if (typeof input === "number") { return input; } return null; } function parseIsoWeekday(input, locale2) { if (typeof input === "string") { return locale2.weekdaysParse(input) % 7 || 7; } return isNaN(input) ? null : input; } function shiftWeekdays(ws, n) { return ws.slice(n, 7).concat(ws.slice(0, n)); } 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(m, format2) { var weekdays = isArray3(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format2) ? "format" : "standalone"]; return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays; } function localeWeekdaysShort(m) { return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort; } function localeWeekdaysMin(m) { return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin; } function handleStrictParse$1(weekdayName, format2, strict) { var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); if (!this._weekdaysParse) { this._weekdaysParse = []; this._shortWeekdaysParse = []; this._minWeekdaysParse = []; for (i = 0; i < 7; ++i) { mom = createUTC([2e3, 1]).day(i); this._minWeekdaysParse[i] = this.weekdaysMin(mom, "").toLocaleLowerCase(); this._shortWeekdaysParse[i] = this.weekdaysShort(mom, "").toLocaleLowerCase(); this._weekdaysParse[i] = 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 i, 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 (i = 0; i < 7; i++) { mom = createUTC([2e3, 1]).day(i); if (strict && !this._fullWeekdaysParse[i]) { this._fullWeekdaysParse[i] = new RegExp("^" + this.weekdays(mom, "").replace(".", "\\.?") + "$", "i"); this._shortWeekdaysParse[i] = new RegExp("^" + this.weekdaysShort(mom, "").replace(".", "\\.?") + "$", "i"); this._minWeekdaysParse[i] = new RegExp("^" + this.weekdaysMin(mom, "").replace(".", "\\.?") + "$", "i"); } if (!this._weekdaysParse[i]) { regex = "^" + this.weekdays(mom, "") + "|^" + this.weekdaysShort(mom, "") + "|^" + this.weekdaysMin(mom, ""); this._weekdaysParse[i] = new RegExp(regex.replace(".", ""), "i"); } if (strict && format2 === "dddd" && this._fullWeekdaysParse[i].test(weekdayName)) { return i; } else if (strict && format2 === "ddd" && this._shortWeekdaysParse[i].test(weekdayName)) { return i; } else if (strict && format2 === "dd" && this._minWeekdaysParse[i].test(weekdayName)) { return i; } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { return i; } } } 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(a, b) { return b.length - a.length; } var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], i, mom, minp, shortp, longp; for (i = 0; i < 7; i++) { mom = createUTC([2e3, 1]).day(i); 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, locale2) { return locale2._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, config2) { var kInput = toInt(input); array[HOUR] = kInput === 24 ? 0 : kInput; }); addParseToken(["a", "A"], function(input, array, config2) { config2._isPm = config2._locale.isPM(input); config2._meridiem = input; }); addParseToken(["h", "hh"], function(input, array, config2) { array[HOUR] = toInt(input); getParsingFlags(config2).bigHour = true; }); addParseToken("hmm", function(input, array, config2) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); getParsingFlags(config2).bigHour = true; }); addParseToken("hmmss", function(input, array, config2) { 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(config2).bigHour = true; }); addParseToken("Hmm", function(input, array, config2) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); }); addParseToken("Hmmss", function(input, array, config2) { 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 i, minl = Math.min(arr1.length, arr2.length); for (i = 0; i < minl; i += 1) { if (arr1[i] !== arr2[i]) { return i; } } return minl; } function normalizeLocale(key) { return key ? key.toLowerCase().replace("_", "-") : key; } function chooseLocale(names) { var i = 0, j, next, locale2, split; while (i < names.length) { split = normalizeLocale(names[i]).split("-"); j = split.length; next = normalizeLocale(names[i + 1]); next = next ? next.split("-") : null; while (j > 0) { locale2 = loadLocale(split.slice(0, j).join("-")); if (locale2) { return locale2; } if (next && next.length >= j && commonPrefix(split, next) >= j - 1) { break; } j--; } i++; } return globalLocale; } function isLocaleNameSane(name) { return !!(name && name.match("^[^/\\\\]*$")); } function loadLocale(name) { var oldLocale = null, aliasedRequire; if (locales[name] === void 0 && typeof module !== "undefined" && module && module.exports && isLocaleNameSane(name)) { try { oldLocale = globalLocale._abbr; aliasedRequire = __require; aliasedRequire("./locale/" + name); getSetGlobalLocale(oldLocale); } catch (e) { locales[name] = null; } } return locales[name]; } function getSetGlobalLocale(key, values) { var data; if (key) { if (isUndefined2(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, config2) { if (config2 !== null) { var locale2, parentConfig = baseConfig; config2.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 (config2.parentLocale != null) { if (locales[config2.parentLocale] != null) { parentConfig = locales[config2.parentLocale]._config; } else { locale2 = loadLocale(config2.parentLocale); if (locale2 != null) { parentConfig = locale2._config; } else { if (!localeFamilies[config2.parentLocale]) { localeFamilies[config2.parentLocale] = []; } localeFamilies[config2.parentLocale].push({ name, config: config2 }); return null; } } } locales[name] = new Locale(mergeConfigs(parentConfig, config2)); if (localeFamilies[name]) { localeFamilies[name].forEach(function(x) { defineLocale(x.name, x.config); }); } getSetGlobalLocale(name); return locales[name]; } else { delete locales[name]; return null; } } function updateLocale(name, config2) { if (config2 != null) { var locale2, tmpLocale, parentConfig = baseConfig; if (locales[name] != null && locales[name].parentLocale != null) { locales[name].set(mergeConfigs(locales[name]._config, config2)); } else { tmpLocale = loadLocale(name); if (tmpLocale != null) { parentConfig = tmpLocale._config; } config2 = mergeConfigs(parentConfig, config2); if (tmpLocale == null) { config2.abbr = name; } locale2 = new Locale(config2); locale2.parentLocale = locales[name]; locales[name] = locale2; } 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 locale2; if (key && key._locale && key._locale._abbr) { key = key._locale._abbr; } if (!key) { return globalLocale; } if (!isArray3(key)) { locale2 = loadLocale(key); if (locale2) { return locale2; } key = [key]; } return chooseLocale(key); } function listLocales() { return keys2(locales); } function checkOverflow(m) { var overflow, a = m._a; if (a && getParsingFlags(m).overflow === -2) { overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1; if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { overflow = DATE; } if (getParsingFlags(m)._overflowWeeks && overflow === -1) { overflow = WEEK; } if (getParsingFlags(m)._overflowWeekday && overflow === -1) { overflow = WEEKDAY; } getParsingFlags(m).overflow = overflow; } return m; } 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(config2) { var i, l, string = config2._i, match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), allowTime, dateFormat, timeFormat, tzFormat, isoDatesLen = isoDates.length, isoTimesLen = isoTimes.length; if (match) { getParsingFlags(config2).iso = true; for (i = 0, l = isoDatesLen; i < l; i++) { if (isoDates[i][1].exec(match[1])) { dateFormat = isoDates[i][0]; allowTime = isoDates[i][2] !== false; break; } } if (dateFormat == null) { config2._isValid = false; return; } if (match[3]) { for (i = 0, l = isoTimesLen; i < l; i++) { if (isoTimes[i][1].exec(match[3])) { timeFormat = (match[2] || " ") + isoTimes[i][0]; break; } } if (timeFormat == null) { config2._isValid = false; return; } } if (!allowTime && timeFormat != null) { config2._isValid = false; return; } if (match[4]) { if (tzRegex.exec(match[4])) { tzFormat = "Z"; } else { config2._isValid = false; return; } } config2._f = dateFormat + (timeFormat || "") + (tzFormat || ""); configFromStringAndFormat(config2); } else { config2._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(s) { return s.replace(/\([^()]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").replace(/^\s\s*/, "").replace(/\s\s*$/, ""); } function checkWeekday(weekdayStr, parsedInput, config2) { if (weekdayStr) { var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); if (weekdayProvided !== weekdayActual) { getParsingFlags(config2).weekdayMismatch = true; config2._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), m = hm % 100, h = (hm - m) / 100; return h * 60 + m; } } function configFromRFC2822(config2) { var match = rfc2822.exec(preprocessRFC2822(config2._i)), parsedArray; if (match) { parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); if (!checkWeekday(match[1], parsedArray, config2)) { return; } config2._a = parsedArray; config2._tzm = calculateOffset(match[8], match[9], match[10]); config2._d = createUTCDate.apply(null, config2._a); config2._d.setUTCMinutes(config2._d.getUTCMinutes() - config2._tzm); getParsingFlags(config2).rfc2822 = true; } else { config2._isValid = false; } } function configFromString(config2) { var matched = aspNetJsonRegex.exec(config2._i); if (matched !== null) { config2._d = new Date(+matched[1]); return; } configFromISO(config2); if (config2._isValid === false) { delete config2._isValid; } else { return; } configFromRFC2822(config2); if (config2._isValid === false) { delete config2._isValid; } else { return; } if (config2._strict) { config2._isValid = false; } else { hooks.createFromInputFallback(config2); } } 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(config2) { config2._d = new Date(config2._i + (config2._useUTC ? " UTC" : "")); }); function defaults(a, b, c) { if (a != null) { return a; } if (b != null) { return b; } return c; } function currentDateArray(config2) { var nowValue = new Date(hooks.now()); if (config2._useUTC) { return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; } return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; } function configFromArray(config2) { var i, date, input = [], currentDate, expectedWeekday, yearToUse; if (config2._d) { return; } currentDate = currentDateArray(config2); if (config2._w && config2._a[DATE] == null && config2._a[MONTH] == null) { dayOfYearFromWeekInfo(config2); } if (config2._dayOfYear != null) { yearToUse = defaults(config2._a[YEAR], currentDate[YEAR]); if (config2._dayOfYear > daysInYear(yearToUse) || config2._dayOfYear === 0) { getParsingFlags(config2)._overflowDayOfYear = true; } date = createUTCDate(yearToUse, 0, config2._dayOfYear); config2._a[MONTH] = date.getUTCMonth(); config2._a[DATE] = date.getUTCDate(); } for (i = 0; i < 3 && config2._a[i] == null; ++i) { config2._a[i] = input[i] = currentDate[i]; } for (; i < 7; i++) { config2._a[i] = input[i] = config2._a[i] == null ? i === 2 ? 1 : 0 : config2._a[i]; } if (config2._a[HOUR] === 24 && config2._a[MINUTE] === 0 && config2._a[SECOND] === 0 && config2._a[MILLISECOND] === 0) { config2._nextDay = true; config2._a[HOUR] = 0; } config2._d = (config2._useUTC ? createUTCDate : createDate).apply(null, input); expectedWeekday = config2._useUTC ? config2._d.getUTCDay() : config2._d.getDay(); if (config2._tzm != null) { config2._d.setUTCMinutes(config2._d.getUTCMinutes() - config2._tzm); } if (config2._nextDay) { config2._a[HOUR] = 24; } if (config2._w && typeof config2._w.d !== "undefined" && config2._w.d !== expectedWeekday) { getParsingFlags(config2).weekdayMismatch = true; } } function dayOfYearFromWeekInfo(config2) { var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek; w = config2._w; if (w.GG != null || w.W != null || w.E != null) { dow = 1; doy = 4; weekYear = defaults(w.GG, config2._a[YEAR], weekOfYear(createLocal(), 1, 4).year); week = defaults(w.W, 1); weekday = defaults(w.E, 1); if (weekday < 1 || weekday > 7) { weekdayOverflow = true; } } else { dow = config2._locale._week.dow; doy = config2._locale._week.doy; curWeek = weekOfYear(createLocal(), dow, doy); weekYear = defaults(w.gg, config2._a[YEAR], curWeek.year); week = defaults(w.w, curWeek.week); if (w.d != null) { weekday = w.d; if (weekday < 0 || weekday > 6) { weekdayOverflow = true; } } else if (w.e != null) { weekday = w.e + dow; if (w.e < 0 || w.e > 6) { weekdayOverflow = true; } } else { weekday = dow; } } if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { getParsingFlags(config2)._overflowWeeks = true; } else if (weekdayOverflow != null) { getParsingFlags(config2)._overflowWeekday = true; } else { temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); config2._a[YEAR] = temp.year; config2._dayOfYear = temp.dayOfYear; } } hooks.ISO_8601 = function() { }; hooks.RFC_2822 = function() { }; function configFromStringAndFormat(config2) { if (config2._f === hooks.ISO_8601) { configFromISO(config2); return; } if (config2._f === hooks.RFC_2822) { configFromRFC2822(config2); return; } config2._a = []; getParsingFlags(config2).empty = true; var string = "" + config2._i, i, parsedInput, tokens2, token2, skipped, stringLength = string.length, totalParsedInputLength = 0, era, tokenLen; tokens2 = expandFormat(config2._f, config2._locale).match(formattingTokens) || []; tokenLen = tokens2.length; for (i = 0; i < tokenLen; i++) { token2 = tokens2[i]; parsedInput = (string.match(getParseRegexForToken(token2, config2)) || [])[0]; if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { getParsingFlags(config2).unusedInput.push(skipped); } string = string.slice(string.indexOf(parsedInput) + parsedInput.length); totalParsedInputLength += parsedInput.length; } if (formatTokenFunctions[token2]) { if (parsedInput) { getParsingFlags(config2).empty = false; } else { getParsingFlags(config2).unusedTokens.push(token2); } addTimeToArrayFromToken(token2, parsedInput, config2); } else if (config2._strict && !parsedInput) { getParsingFlags(config2).unusedTokens.push(token2); } } getParsingFlags(config2).charsLeftOver = stringLength - totalParsedInputLength; if (string.length > 0) { getParsingFlags(config2).unusedInput.push(string); } if (config2._a[HOUR] <= 12 && getParsingFlags(config2).bigHour === true && config2._a[HOUR] > 0) { getParsingFlags(config2).bigHour = void 0; } getParsingFlags(config2).parsedDateParts = config2._a.slice(0); getParsingFlags(config2).meridiem = config2._meridiem; config2._a[HOUR] = meridiemFixWrap(config2._locale, config2._a[HOUR], config2._meridiem); era = getParsingFlags(config2).era; if (era !== null) { config2._a[YEAR] = config2._locale.erasConvertYear(era, config2._a[YEAR]); } configFromArray(config2); checkOverflow(config2); } function meridiemFixWrap(locale2, hour, meridiem2) { var isPm; if (meridiem2 == null) { return hour; } if (locale2.meridiemHour != null) { return locale2.meridiemHour(hour, meridiem2); } else if (locale2.isPM != null) { isPm = locale2.isPM(meridiem2); if (isPm && hour < 12) { hour += 12; } if (!isPm && hour === 12) { hour = 0; } return hour; } else { return hour; } } function configFromStringAndArray(config2) { var tempConfig, bestMoment, scoreToBeat, i, currentScore, validFormatFound, bestFormatIsValid = false, configfLen = config2._f.length; if (configfLen === 0) { getParsingFlags(config2).invalidFormat = true; config2._d = new Date(NaN); return; } for (i = 0; i < configfLen; i++) { currentScore = 0; validFormatFound = false; tempConfig = copyConfig({}, config2); if (config2._useUTC != null) { tempConfig._useUTC = config2._useUTC; } tempConfig._f = config2._f[i]; 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; } } } extend2(config2, bestMoment || tempConfig); } function configFromObject(config2) { if (config2._d) { return; } var i = normalizeObjectUnits(config2._i), dayOrDate = i.day === void 0 ? i.date : i.day; config2._a = map([i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond], function(obj) { return obj && parseInt(obj, 10); }); configFromArray(config2); } function createFromConfig(config2) { var res = new Moment2(checkOverflow(prepareConfig(config2))); if (res._nextDay) { res.add(1, "d"); res._nextDay = void 0; } return res; } function prepareConfig(config2) { var input = config2._i, format2 = config2._f; config2._locale = config2._locale || getLocale(config2._l); if (input === null || format2 === void 0 && input === "") { return createInvalid({ nullInput: true }); } if (typeof input === "string") { config2._i = input = config2._locale.preparse(input); } if (isMoment(input)) { return new Moment2(checkOverflow(input)); } else if (isDate(input)) { config2._d = input; } else if (isArray3(format2)) { configFromStringAndArray(config2); } else if (format2) { configFromStringAndFormat(config2); } else { configFromInput(config2); } if (!isValid(config2)) { config2._d = null; } return config2; } function configFromInput(config2) { var input = config2._i; if (isUndefined2(input)) { config2._d = new Date(hooks.now()); } else if (isDate(input)) { config2._d = new Date(input.valueOf()); } else if (typeof input === "string") { configFromString(config2); } else if (isArray3(input)) { config2._a = map(input.slice(0), function(obj) { return parseInt(obj, 10); }); configFromArray(config2); } else if (isObject2(input)) { configFromObject(config2); } else if (isNumber2(input)) { config2._d = new Date(input); } else { hooks.createFromInputFallback(config2); } } function createLocalOrUTC(input, format2, locale2, strict, isUTC) { var c = {}; if (format2 === true || format2 === false) { strict = format2; format2 = void 0; } if (locale2 === true || locale2 === false) { strict = locale2; locale2 = void 0; } if (isObject2(input) && isObjectEmpty(input) || isArray3(input) && input.length === 0) { input = void 0; } c._isAMomentObject = true; c._useUTC = c._isUTC = isUTC; c._l = locale2; c._i = input; c._f = format2; c._strict = strict; return createFromConfig(c); } function createLocal(input, format2, locale2, strict) { return createLocalOrUTC(input, format2, locale2, 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(fn, moments) { var res, i; if (moments.length === 1 && isArray3(moments[0])) { moments = moments[0]; } if (!moments.length) { return createLocal(); } res = moments[0]; for (i = 1; i < moments.length; ++i) { if (!moments[i].isValid() || moments[i][fn](res)) { res = moments[i]; } } 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 now = function() { return Date.now ? Date.now() : + new Date(); }; var ordering = ["year", "quarter", "month", "week", "day", "hour", "minute", "second", "millisecond"]; function isDurationValid(m) { var key, unitHasDecimal = false, i, orderLen = ordering.length; for (key in m) { if (hasOwnProp(m, key) && !(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { return false; } } for (i = 0; i < orderLen; ++i) { if (m[ordering[i]]) { if (unitHasDecimal) { return false; } if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { 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 + minutes2 * 6e4 + 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 compareArrays2(array1, array2, dontConvert) { var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), diffs = 0, i; for (i = 0; i < len; i++) { if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) { diffs++; } } return diffs + lengthDiff; } function offset(token2, separator) { addFormatToken(token2, 0, 0, function() { var offset2 = this.utcOffset(), sign2 = "+"; if (offset2 < 0) { offset2 = -offset2; sign2 = "-"; } return sign2 + 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, config2) { config2._useUTC = true; config2._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(m) { return -Math.round(m._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 (!isUndefined2(this._isDSTShifted)) { return this._isDSTShifted; } var c = {}, other; copyConfig(c, this); c = prepareConfig(c); if (c._a) { other = c._isUTC ? createUTC(c._a) : createLocal(c._a); this._isDSTShifted = this.isValid() && compareArrays2(c._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, match = null, sign2, 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 (match = aspNetRegex.exec(input)) { sign2 = match[1] === "-" ? -1 : 1; duration = { y: 0, d: toInt(match[DATE]) * sign2, h: toInt(match[HOUR]) * sign2, m: toInt(match[MINUTE]) * sign2, s: toInt(match[SECOND]) * sign2, ms: toInt(absRound(match[MILLISECOND] * 1e3)) * sign2 }; } else if (match = isoRegex.exec(input)) { sign2 = match[1] === "-" ? -1 : 1; duration = { y: parseIso(match[2], sign2), M: parseIso(match[3], sign2), w: parseIso(match[4], sign2), d: parseIso(match[5], sign2), h: parseIso(match[6], sign2), m: parseIso(match[7], sign2), s: parseIso(match[8], sign2) }; } 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, sign2) { var res = inp && parseFloat(inp.replace(",", ".")); return (isNaN(res) ? 0 : res) * sign2; } 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 isString2(input) { return typeof input === "string" || input instanceof String; } function isMomentInput(input) { return isMoment(input) || isDate(input) || isString2(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"], i, property, propertyLen = properties.length; for (i = 0; i < propertyLen; i += 1) { property = properties[i]; propertyTest = propertyTest || hasOwnProp(input, property); } return objectTest && propertyTest; } function isNumberOrStringArray(input) { var arrayTest = isArray3(input), dataTypeTest = false; if (arrayTest) { dataTypeTest = input.filter(function(item) { return !isNumber2(item) && isString2(input); }).length === 0; } return arrayTest && dataTypeTest; } function isCalendarSpec(input) { var objectTest = isObject2(input) && !isObjectEmpty(input), propertyTest = false, properties = ["sameDay", "nextDay", "lastDay", "nextWeek", "lastWeek", "sameElse"], i, property; for (i = 0; i < properties.length; i += 1) { property = properties[i]; propertyTest = propertyTest || hasOwnProp(input, property); } return objectTest && propertyTest; } function getCalendarFormat(myMoment, now2) { var diff2 = myMoment.diff(now2, "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 now2 = time || createLocal(), sod = cloneWithOffset(now2, this).startOf("day"), format2 = hooks.calendarFormat(this, sod) || "sameElse", output = formats && (isFunction(formats[format2]) ? formats[format2].call(this, now2) : formats[format2]); return this.format(output || this.localeData().calendar(format2, this, createLocal(now2))); } function clone() { return new Moment2(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(from2, to2, units, inclusivity) { var localFrom = isMoment(from2) ? from2 : createLocal(from2), localTo = isMoment(to2) ? to2 : createLocal(to2); 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; case "minute": output = (this - that) / 6e4; break; case "hour": output = (this - that) / 36e5; break; case "day": output = (this - that - zoneDelta) / 864e5; break; case "week": output = (this - that - zoneDelta) / 6048e5; break; default: output = this - that; } return asFloat ? output : absFloor(output); } function monthDiff(a, b) { if (a.date() < b.date()) { return -monthDiff(b, a); } var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()), anchor = a.clone().add(wholeMonthDiff, "months"), anchor2, adjust; if (b - anchor < 0) { anchor2 = a.clone().add(wholeMonthDiff - 1, "months"); adjust = (b - anchor) / (anchor - anchor2); } else { anchor2 = a.clone().add(wholeMonthDiff + 1, "months"); adjust = (b - anchor) / (anchor2 - anchor); } return -(wholeMonthDiff + adjust) || 0; } hooks.defaultFormat = "YYYY-MM-DDTHH:mm:ssZ"; hooks.defaultFormatUtc = "YYYY-MM-DDTHH:mm:ss[Z]"; function toString2() { 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, m = utc ? this.clone().utc() : this; if (m.year() < 0 || m.year() > 9999) { return formatMoment(m, utc ? "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"); } if (isFunction(Date.prototype.toISOString)) { if (utc) { return this.toDate().toISOString(); } else { return new Date(this.valueOf() + this.utcOffset() * 60 * 1e3).toISOString().replace("Z", formatMoment(m, "Z")); } } return formatMoment(m, 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 from(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 to(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 locale(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(y, m, d) { if (y < 100 && y >= 0) { return new Date(y + 400, m, d) - MS_PER_400_YEARS; } else { return new Date(y, m, d).valueOf(); } } function utcStartOfDate(y, m, d) { if (y < 100 && y >= 0) { return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; } else { return Date.UTC(y, m, d); } } 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 m = this; return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; } function toObject() { var m = this; return { years: m.year(), months: m.month(), date: m.date(), hours: m.hours(), minutes: m.minutes(), seconds: m.seconds(), milliseconds: m.milliseconds() }; } function toJSON() { return this.isValid() ? this.toISOString() : null; } function isValid$2() { return isValid(this); } function parsingFlags() { return extend2({}, 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, config2, token2) { var era = config2._locale.erasParse(input, token2, config2._strict); if (era) { getParsingFlags(config2).era = era; } else { getParsingFlags(config2).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, config2, token2) { var match; if (config2._locale._eraYearOrdinalRegex) { match = input.match(config2._locale._eraYearOrdinalRegex); } if (config2._locale.eraYearOrdinalParse) { array[YEAR] = config2._locale.eraYearOrdinalParse(input, match); } else { array[YEAR] = parseInt(input, 10); } }); function localeEras(m, format2) { var i, l, date, eras = this._eras || getLocale("en")._eras; for (i = 0, l = eras.length; i < l; ++i) { switch (typeof eras[i].since) { case "string": date = hooks(eras[i].since).startOf("day"); eras[i].since = date.valueOf(); break; } switch (typeof eras[i].until) { case "undefined": eras[i].until = Infinity; break; case "string": date = hooks(eras[i].until).startOf("day").valueOf(); eras[i].until = date.valueOf(); break; } } return eras; } function localeErasParse(eraName, format2, strict) { var i, l, eras = this.eras(), name, abbr, narrow; eraName = eraName.toUpperCase(); for (i = 0, l = eras.length; i < l; ++i) { name = eras[i].name.toUpperCase(); abbr = eras[i].abbr.toUpperCase(); narrow = eras[i].narrow.toUpperCase(); if (strict) { switch (format2) { case "N": case "NN": case "NNN": if (abbr === eraName) { return eras[i]; } break; case "NNNN": if (name === eraName) { return eras[i]; } break; case "NNNNN": if (narrow === eraName) { return eras[i]; } break; } } else if ([name, abbr, narrow].indexOf(eraName) >= 0) { return eras[i]; } } } 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 i, l, val, eras = this.localeData().eras(); for (i = 0, l = eras.length; i < l; ++i) { val = this.clone().startOf("day").valueOf(); if (eras[i].since <= val && val <= eras[i].until) { return eras[i].name; } if (eras[i].until <= val && val <= eras[i].since) { return eras[i].name; } } return ""; } function getEraNarrow() { var i, l, val, eras = this.localeData().eras(); for (i = 0, l = eras.length; i < l; ++i) { val = this.clone().startOf("day").valueOf(); if (eras[i].since <= val && val <= eras[i].until) { return eras[i].narrow; } if (eras[i].until <= val && val <= eras[i].since) { return eras[i].narrow; } } return ""; } function getEraAbbr() { var i, l, val, eras = this.localeData().eras(); for (i = 0, l = eras.length; i < l; ++i) { val = this.clone().startOf("day").valueOf(); if (eras[i].since <= val && val <= eras[i].until) { return eras[i].abbr; } if (eras[i].until <= val && val <= eras[i].since) { return eras[i].abbr; } } return ""; } function getEraYear() { var i, l, dir, val, eras = this.localeData().eras(); for (i = 0, l = eras.length; i < l; ++i) { dir = eras[i].since <= eras[i].until ? 1 : -1; val = this.clone().startOf("day").valueOf(); if (eras[i].since <= val && val <= eras[i].until || eras[i].until <= val && val <= eras[i].since) { return (this.year() - hooks(eras[i].since).year()) * dir + eras[i].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, locale2) { return locale2.erasAbbrRegex(isStrict); } function matchEraName(isStrict, locale2) { return locale2.erasNameRegex(isStrict); } function matchEraNarrow(isStrict, locale2) { return locale2.erasNarrowRegex(isStrict); } function matchEraYearOrdinal(isStrict, locale2) { return locale2._eraYearOrdinalRegex || matchUnsigned; } function computeErasParse() { var abbrPieces = [], namePieces = [], narrowPieces = [], mixedPieces = [], i, l, erasName, erasAbbr, erasNarrow, eras = this.eras(); for (i = 0, l = eras.length; i < l; ++i) { erasName = regexEscape(eras[i].name); erasAbbr = regexEscape(eras[i].abbr); erasNarrow = regexEscape(eras[i].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, config2, token2) { week[token2.substr(0, 2)] = toInt(input); }); addWeekParseToken(["gg", "GG"], function(input, week, config2, 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, locale2) { return isStrict ? locale2._dayOfMonthOrdinalParse || locale2._ordinalParse : locale2._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, config2) { config2._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 = Moment2.prototype; proto.add = add; proto.calendar = calendar$1; proto.clone = clone; proto.diff = diff; proto.endOf = endOf; proto.format = format; proto.from = from; proto.fromNow = fromNow; proto.to = to; 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 = locale; 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 = toString2; 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 = set; 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 locale2 = getLocale(), utc = createUTC().set(setter, index); return locale2[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 i, out = []; for (i = 0; i < 12; i++) { out[i] = get$1(format2, i, 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 locale2 = getLocale(), shift = localeSorted ? locale2._week.dow : 0, i, out = []; if (index != null) { return get$1(format2, (index + shift) % 7, field, "day"); } for (i = 0; i < 7; i++) { out[i] = get$1(format2, (i + 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 b = number % 10, output = toInt(number % 100 / 10) === 1 ? "th" : b === 1 ? "st" : b === 2 ? "nd" : b === 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; 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 round = Math.round, thresholds = { ss: 44, s: 45, m: 45, h: 22, d: 26, w: null, M: 11 }; function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale2) { return locale2.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } function relativeTime$1(posNegDuration, withoutSuffix, thresholds2, locale2) { var duration = createDuration(posNegDuration).abs(), seconds2 = round(duration.as("s")), minutes2 = round(duration.as("m")), hours2 = round(duration.as("h")), days2 = round(duration.as("d")), months2 = round(duration.as("M")), weeks2 = round(duration.as("w")), years2 = round(duration.as("y")), a = 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) { a = a || weeks2 <= 1 && ["w"] || weeks2 < thresholds2.w && ["ww", weeks2]; } a = a || months2 <= 1 && ["M"] || months2 < thresholds2.M && ["MM", months2] || years2 <= 1 && ["y"] || ["yy", years2]; a[2] = withoutSuffix; a[3] = +posNegDuration > 0; a[4] = locale2; return substituteTimeAgo.apply(null, a); } function getSetRelativeTimeRounding(roundingFunction) { if (roundingFunction === void 0) { return round; } if (typeof roundingFunction === "function") { round = 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, locale2, 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; } } locale2 = this.localeData(); output = relativeTime$1(this, !withSuffix, th, locale2); if (withSuffix) { output = locale2.pastFuture(+this, output); } return locale2.postformat(output); } var abs$1 = Math.abs; function sign(x) { return (x > 0) - (x < 0) || +x; } 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, s, 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; s = seconds2 ? seconds2.toFixed(3).replace(/\.?0+$/, "") : ""; totalSign = total < 0 ? "-" : ""; ymSign = sign(this._months) !== sign(total) ? "-" : ""; daysSign = sign(this._days) !== sign(total) ? "-" : ""; hmsSign = sign(this._milliseconds) !== sign(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 + s + "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 = locale; 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, config2) { config2._d = new Date(parseFloat(input) * 1e3); }); addParseToken("x", function(input, array, config2) { config2._d = new Date(toInt(input)); }); hooks.version = "2.30.1"; setHookCallback(createLocal); hooks.fn = proto; hooks.min = min; hooks.max = max; hooks.now = now; 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; }); } }); var ConvertibleNumber = Symbol("ConvertibleNumber"); var PositiveInteger = Symbol("PositiveInteger"); var NegativeInteger = Symbol("NegativeInteger"); var PositiveFloat = Symbol("PositiveFloat"); var NegativeFloat = Symbol("NegativeFloat"); var emojiSeq = String.raw`(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})`; var emojiSTags = String.raw`\u{E0061}-\u{E007A}`; var emojiRegex = new RegExp(String.raw`[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[${emojiSTags}]{2}[\u{E0030}-\u{E0039}${emojiSTags}]{1,3}\u{E007F}|${emojiSeq}(?:\u200D${emojiSeq})*`, "gu"); var isNull = (obj) => obj === null; var isUndefined = (obj) => typeof obj === "undefined"; var isNullOrUndefined = (obj) => isUndefined(obj) || isNull(obj); var isObject = (obj) => !isNullOrUndefined(obj) && typeof obj === "object" && !Array.isArray(obj); var isString = (obj) => !isNullOrUndefined(obj) && typeof obj === "string"; var isNumber = (obj) => !isNullOrUndefined(obj) && typeof obj === "number"; var isArray = (obj) => Array.isArray(obj); var isElement = (obj) => !isNullOrUndefined(obj) && obj instanceof Element; var isNode = (obj) => !isNullOrUndefined(obj) && obj instanceof Node; var isNotEmpty = (obj) => { if (isNullOrUndefined(obj)) { return false; } if (Array.isArray(obj)) { return obj.some(isNotEmpty); } if (isString(obj)) { return !obj.isEmpty(); } if (isNumber(obj)) { return !Number.isNaN(obj); } if (isElement(obj) || isNode(obj)) { return true; } if (isObject(obj)) { return Object.values(obj).some(isNotEmpty); } return true; }; var isVideoInfo = (obj) => { if (obj === null || typeof obj !== "object") return false; const info = obj; return isInitVideoInfo(info) || isFullVideoInfo(info) || isPartialVideoInfo(info) || isCacheVideoInfo(info) || isFailVideoInfo(info); }; var hasValidID = (info) => isString(info.ID) && isNotEmpty(info.ID); var isInitVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "init" && hasValidID(info); var isFullVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "full" && hasValidID(info) && isNumber(info.UploadTime) && isString(info.Title) && isNotEmpty(info.Title) && isString(info.FileName) && isNotEmpty(info.FileName) && isNumber(info.Size) && isArray(info.Tags) && typeof info.Liked === "boolean" && typeof info.Following === "boolean" && typeof info.Friend === "boolean" && isString(info.Author) && isNotEmpty(info.Author) && isString(info.AuthorID) && isNotEmpty(info.AuthorID) && typeof info.Private === "boolean" && typeof info.Unlisted === "boolean" && isString(info.DownloadQuality) && typeof info.External === "boolean" && isString(info.DownloadUrl) && isNotEmpty(info.DownloadUrl) && isObject(info.RAW); var isPartialVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "partial" && hasValidID(info) && isNumber(info.UploadTime) && isString(info.Title) && isNotEmpty(info.Title) && isArray(info.Tags) && typeof info.Liked === "boolean" && isString(info.Author) && isNotEmpty(info.Author) && isString(info.AuthorID) && isNotEmpty(info.AuthorID) && typeof info.Private === "boolean" && typeof info.Unlisted === "boolean" && typeof info.External === "boolean" && isObject(info.RAW); var isCacheVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "cache" && hasValidID(info) && isObject(info.RAW); var isFailVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "fail" && hasValidID(info); var assertVideoInfoType = (info) => { switch (info.Type) { case "init": return info; case "full": return info; case "partial": return info; case "cache": return info; case "fail": return info; default: throw new Error(`未知的 VideoInfo 类型: ${info.Type}`); } }; function isConvertibleToNumber(obj, includeInfinity = false) { if (isNullOrUndefined(obj)) { return false; } if (isString(obj)) { return obj.isConvertibleToNumber(includeInfinity); } if (isNumber(obj)) { return isNaN(obj) ? false : includeInfinity ? true : isFinite(obj); } return false; } Number.isConvertibleNumber = (value, includeInfinity = false) => { if (isNullOrUndefined(value)) { return false; } if (isString(value)) { return value.isConvertibleToNumber(includeInfinity); } if (isNumber(value)) { return isNaN(value) ? false : includeInfinity ? true : isFinite(value); } return false; }; Number.isPositiveInteger = (value) => typeof value === "number" && Number.isInteger(value) && value > 0; Number.isNegativeInteger = (value) => typeof value === "number" && Number.isInteger(value) && value < 0; Number.isPositiveFloat = (value) => typeof value === "number" && !Number.isInteger(value) && value > 0; Number.isNegativeFloat = (value) => typeof value === "number" && !Number.isInteger(value) && value < 0; Number.toPositiveInteger = (value) => { if (!Number.isPositiveInteger(value)) { throw new Error("值必须为正整数"); } return value; }; Number.toNegativeInteger = (value) => { if (!Number.isNegativeInteger(value)) { throw new Error("值必须为负整数"); } return value; }; Number.toPositiveFloat = (value) => { if (!Number.isPositiveFloat(value)) { throw new Error("值必须为正浮点数"); } return value; }; Number.toNegativeFloat = (value) => { if (!Number.isNegativeFloat(value)) { throw new Error("值必须为负浮点数"); } return value; }; Array.prototype.any = function() { return this.filter((i) => !isNullOrUndefined(i)).length > 0; }; Array.prototype.unique = function(prop) { if (isNullOrUndefined(prop)) { const seen = new Set(); return this.filter((item) => { if (seen.has(item)) return false; seen.add(item); return true; }); } else { const seen = new Map(); const nanSymbol = Symbol(); return this.filter((item) => { const rawKey = item[prop]; const key = isNumber(rawKey) && Number.isNaN(rawKey) ? nanSymbol : rawKey; if (seen.has(key)) return false; seen.set(key, true); return true; }); } }; Array.prototype.union = function(that, prop) { return [...this, ...that].unique(prop); }; Array.prototype.intersect = function(that, prop) { return this.filter((item) => that.some((t) => isNullOrUndefined(prop) ? t === item : t[prop] === item[prop])).unique(prop); }; Array.prototype.difference = function(that, prop) { return this.filter((item) => !that.some((t) => isNullOrUndefined(prop) ? t === item : t[prop] === item[prop])).unique(prop); }; Array.prototype.complement = function(that, prop) { return this.union(that, prop).difference(this.intersect(that, prop), prop); }; String.prototype.isEmpty = function() { return !isNullOrUndefined(this) && this.length === 0; }; String.prototype.isConvertibleToNumber = function(includeInfinity = false) { const trimmed = this.trim(); if (trimmed === "") return false; return Number.isConvertibleNumber(Number(trimmed), includeInfinity); }; String.prototype.reversed = function() { const segmenter = new Intl.Segmenter(navigator.language, { granularity: "grapheme" }); return [...segmenter.segment(this.toString())].reverse().join(""); }; String.prototype.among = function(start, end, greedy = false, reverse = false) { if (this.isEmpty() || start.isEmpty() || end.isEmpty()) return ""; if (!reverse) { const startIndex = this.indexOf(start); if (startIndex === -1) return ""; const adjustedStartIndex = startIndex + start.length; const endIndex = greedy ? this.lastIndexOf(end) : this.indexOf(end, adjustedStartIndex); if (endIndex === -1 || endIndex < adjustedStartIndex) return ""; return this.slice(adjustedStartIndex, endIndex); } else { const endIndex = this.lastIndexOf(end); if (endIndex === -1) return ""; const adjustedEndIndex = endIndex - end.length; const startIndex = greedy ? this.indexOf(start) : this.lastIndexOf(start, adjustedEndIndex); if (startIndex === -1 || startIndex + start.length > adjustedEndIndex) return ""; return this.slice(startIndex + start.length, endIndex); } }; String.prototype.splitLimit = function(separator, limit) { if (this.isEmpty() || isNullOrUndefined(separator)) { throw new Error("Empty"); } let body = this.split(separator); return limit ? body.slice(0, limit).concat(body.slice(limit).join(separator)) : body; }; String.prototype.truncate = function(maxLength) { return this.length > maxLength ? this.substring(0, maxLength) : this.toString(); }; String.prototype.trimHead = function(prefix) { return this.startsWith(prefix) ? this.slice(prefix.length) : this.toString(); }; String.prototype.trimTail = function(suffix) { return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this.toString(); }; String.prototype.replaceEmojis = function(replace) { return this.replaceAll(emojiRegex, replace ?? ""); }; String.prototype.toURL = function() { let URLString = this; if (URLString.split("//")[0].isEmpty()) { URLString = `${unsafeWindow.location.protocol}${URLString}`; } return new URL(URLString.toString()); }; Date.prototype.add = function({ years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, ms = 0 } = {}) { const newDate = new Date(this.getTime()); if (years) newDate.setFullYear(newDate.getFullYear() + years); if (months) newDate.setMonth(newDate.getMonth() + months); if (days) newDate.setDate(newDate.getDate() + days); if (hours) newDate.setHours(newDate.getHours() + hours); if (minutes) newDate.setMinutes(newDate.getMinutes() + minutes); if (seconds) newDate.setSeconds(newDate.getSeconds() + seconds); if (ms) newDate.setMilliseconds(newDate.getMilliseconds() + ms); return newDate; }; Date.prototype.sub = function({ years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, ms = 0 } = {}) { const newDate = new Date(this.getTime()); if (years) newDate.setFullYear(newDate.getFullYear() - years); if (months) newDate.setMonth(newDate.getMonth() - months); if (days) newDate.setDate(newDate.getDate() - days); if (hours) newDate.setHours(newDate.getHours() - hours); if (minutes) newDate.setMinutes(newDate.getMinutes() - minutes); if (seconds) newDate.setSeconds(newDate.getSeconds() - seconds); if (ms) newDate.setMilliseconds(newDate.getMilliseconds() - ms); return newDate; }; function throttle(fn, delay2, { leading = true, trailing = true } = {}) { let lastCall = 0; let timer = null; const throttled = function(...args) { const now = Date.now(); if (!lastCall && !leading) { lastCall = now; } const remaining = delay2 - (now - lastCall); if (remaining <= 0) { if (timer) { clearTimeout(timer); timer = null; } lastCall = now; fn.apply(this, args); } else if (trailing && !timer) { timer = setTimeout(() => { lastCall = leading ? Date.now() : 0; timer = null; fn.apply(this, args); }, remaining); } }; throttled.cancel = () => { if (timer) { clearTimeout(timer); timer = null; } lastCall = 0; }; return throttled; } function debounce(fn, delay2, { immediate = false } = {}) { let timer = null; const debounced = function(...args) { const callNow = immediate && !timer; if (timer) { clearTimeout(timer); } timer = setTimeout(() => { timer = null; if (!immediate) { fn.apply(this, args); } }, delay2); if (callNow) { fn.apply(this, args); } }; debounced.cancel = () => { if (timer) { clearTimeout(timer); timer = null; } }; return debounced; } function delay(time) { return new Promise((resolve) => setTimeout(resolve, time)); } function hasProperty(element, property) { return property in element; } function hasOwnProperty(element, prop) { return prop in element; } function hasFunction(obj, method) { return isObject(obj) && method in obj && typeof obj[method] === "function"; } ; function UUID() { return isNullOrUndefined(crypto) ? Array.from({ length: 8 }, () => ((1 + Math.random()) * 65536 | 0).toString(16).substring(1)).join("") : crypto.randomUUID().replaceAll("-", ""); } function stringify(data) { switch (typeof data) { case "undefined": return "undefined"; case "boolean": return data ? "true" : "false"; case "number": return String(data); case "string": return data; case "symbol": return data.toString(); case "function": return data.toString(); case "object": if (isNull(data)) { return "null"; } if (data instanceof Error) { return data.toString(); } if (data instanceof Date) { return data.toISOString(); } return JSON.stringify(data, null, 2); default: return "unknown"; } } function prune(data) { if (isElement(data) || isNode(data)) { return data; } if (Array.isArray(data)) { return data.map((item) => prune(item)).filter(isNotEmpty); } if (isObject(data)) { const result = Object.fromEntries(Object.entries(data).filter(([, v]) => isNotEmpty(v)).map(([k, v]) => [k, prune(v)]).filter(([, v]) => isNotEmpty(v))); return result; } return data; } function compareVC(vc1, vc2) { vc1 = vc1 || {}; vc2 = vc2 || {}; let less = false, greater = false; const keys2 = new Set([...Object.keys(vc1), ...Object.keys(vc2)]); for (const k of keys2) { const a = vc1[k] ?? 0; const b = vc2[k] ?? 0; if (a < b) less = true; if (a > b) greater = true; } if (less && !greater) return "before"; if (!less && greater) return "after"; if (!less && !greater) return "equal"; return "concurrent"; } function mergeVC(vc1, vc2) { const result = { ...vc1 }; for (const k in vc2) { result[k] = Math.max(result[k] ?? 0, vc2[k]); } return result; } String.prototype.replaceVariable = function(replacements, prefix = "%#", suffix = "#%") { function escapeRegex(str) { return str.replace(/[\.\*\+\?\^\$\{\}\(\)\|\[\]\\]/g, "\\$&"); } let current = this.toString(); prefix = escapeRegex(prefix); suffix = escapeRegex(suffix); const seen = new Set(); const patterns = Object.keys(replacements).map((key) => { const escKey = escapeRegex(key); return { value: replacements[key], placeholderRegex: new RegExp(`${prefix}${escKey}(?=(?::.*?${suffix}|${suffix}))(?::.*?)?${suffix}`, "gs"), placeholderFormatRegex: new RegExp(`(?<=${prefix}${escKey}(?=(?::.*?${suffix}|${suffix})):).*?(?=${suffix})`, "gs") }; }); while (true) { if (seen.has(current)) { console.warn("检测到循环替换!", `终止于: ${current}`); break; } seen.add(current); let next = current; for (const { value, placeholderRegex, placeholderFormatRegex } of patterns) { if (placeholderRegex.test(next)) { let format = next.match(placeholderFormatRegex); if (!isNullOrUndefined(format) && format.any() && !format[0].isEmpty() && hasFunction(value, "format")) { next = next.replace(placeholderRegex, stringify(value.format(escapeRegex(format[0])))); } else { next = next.replace(placeholderRegex, stringify(value instanceof Date ? value.format("YYYY-MM-DD") : value)); } } } if (current === next) break; current = next; } return current; }; var zh_cn_default = { appName: "Iwara 批量下载工具", language: "语言: ", downloadPriority: "下载画质: ", downloadPath: "下载到: ", downloadProxy: "下载代理: ", downloadProxyUsername: "下载代理用户名: ", downloadProxyPassword: "下载代理密码: ", aria2Path: "Aria2 RPC: ", aria2Token: "Aria2 密钥: ", iwaraDownloaderPath: "IwaraDownloader RPC: ", iwaraDownloaderToken: "IwaraDownloader 密钥: ", experimentalFeatures: "实验性功能", enableUnsafeMode: "激进模式(风险自行承担)", rename: "重命名", save: "保存", reset: "重置", ok: "确定", on: "开启", off: "关闭", delete: "删除", deleteSucceed: "删除成功!", isDebug: "调试模式", downloadType: "下载方式", browserDownload: "浏览器下载", iwaraDownloaderDownload: "IwaraDownloader下载", autoFollow: "自动关注选中的视频作者", autoLike: "自动点赞选中的视频", addUnlistedAndPrivate: "不公开和私有视频强制显示(需关注作者)", checkDownloadLink: "第三方网盘下载地址检查", checkPriority: "下载画质检查", autoDownloadMetadata: "自动下载视频元数据", videoMetadata: "视频元数据", autoInjectCheckbox: "自动注入选择框", notOfficialWarning: "警告,此网站不是Iwara官方网站,请勿填写任何敏感信息!\n继续浏览该网站?", autoCopySaveFileName: "自动复制根据规则生成的文件名", configurationIncompatible: "初始化或配置文件不兼容,请重新配置!", browserDownloadNotEnabled: "未启用下载功能!", browserDownloadNotWhitelisted: "请求的文件扩展名未列入白名单!", browserDownloadNotPermitted: "下载功能已启用,但未授予下载权限!", browserDownloadNotSupported: "目前浏览器/版本不支持下载功能!", browserDownloadNotSucceeded: "下载未开始或失败!", browserDownloadUnknownError: "未知错误,有可能是下载时提供的参数存在问题,请检查文件名是否合法!", browserDownloadTimeout: "下载超时,请检查网络环境是否正常!", variable: "→ 查看可用变量 ←", downloadTime: "下载时间 ", uploadTime: "发布时间 ", example: "示例: ", result: "结果: ", loadingCompleted: "加载完成", settings: "打开设置", downloadThis: "下载当前视频", manualDownload: "手动下载指定", aria2TaskCheck: "Aria2任务重启", reverseSelect: "本页反向选中", deselectThis: "取消本页选中", deselectAll: "取消所有选中", selectThis: "本页全部选中", parseUnlistedAndPrivate: "解析近期隐藏或私有的视频", downloadSelected: "下载所选", selected: "已选中", downloadingSelected: "正在下载所选,请稍后...", injectCheckbox: "开关选择框", configError: "脚本配置中存在错误,请修改。", alreadyKnowHowToUse: "我已知晓如何使用!!!(此页面仅显示一次)", notice: [ "加载完成", { nodeType: "br" }, "公告: ", { nodeType: "br" }, "解决了批量选中或取消选择时多标签页不同步的问题。", { nodeType: "br" }, "添加安全检查,本脚本将拒绝在风险网站上加载功能模块。" ], useHelpForBase: [ "请认真阅读使用指南!", { nodeType: "br" }, "点击网页侧边的灰色侧栏展开脚本菜单,根据需求点击菜单中的功能。" ], useHelpForInjectCheckbox: "打开任意存在视频卡片的页面,脚本会在视频卡片上注入复选框,点击复选框或鼠标悬浮在视频卡片上按空格将会勾选此视频。", useHelpForCheckDownloadLink: "开启“%#checkDownloadLink#%”功能会在下载视频前会检查视频简介以及评论,如果在其中发现疑似第三方网盘下载链接,将会弹出提示,您可以点击提示打开视频页面。", useHelpForManualDownload: [ "使用手动下载功能需要提供视频ID,如需批量手动下载请提供使用“|”分割的视频ID。", { nodeType: "br" }, "例如: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L", { nodeType: "br" }, "或提供符合以下格式对象的数组json字符串", { nodeType: "br" }, "[ ID: string, { Title?: string, Alias?: string, Author?: string } ] ", { nodeType: "br" }, "例如: ", { nodeType: "br" }, '[["AeGUIRO2D5vQ6F", { Title: "237知更鸟", Alias: "骑着牛儿追织女", Author: "user1528210" }],["qQsUMJa19LcK3L", { Title: "Mika Automotive Extradimensional", Alias: "Temptation’s_Symphony", Author: "temptations_symphony" }]]' ], useHelpForBugreport: [ "反馈遇到的BUG、使用问题等请前往: ", { nodeType: "a", childs: "Github", attributes: { href: "https://github.com/dawn-lc/IwaraDownloadTool/" } } ], tryRestartingDownload: "→ 点击此处重新下载 ←", tryReparseDownload: "→ 点击此处重新解析 ←", cdnCacheFinded: "→ 进入 MMD Fans 缓存页面 ←", openVideoLink: "→ 进入视频页面 ←", copySucceed: "复制成功!", pushTaskSucceed: "推送下载任务成功!", exportConfig: "导出配置", exportConfigSucceed: "配置已导出至剪切板!", connectionTest: "连接测试", settingsCheck: "配置检查", createTask: "创建任务", downloadPathError: "下载路径错误!", browserDownloadModeError: "请启用脚本管理器的浏览器API下载模式!", downloadQualityError: "未找到指定的画质下载地址!", findedDownloadLink: "发现疑似第三方网盘下载地址!", allCompleted: "全部解析完成!", parsing: "预解析中...", following: "已关注", parsingProgress: "解析进度: ", manualDownloadTips: '单独下载请直接在此处输入视频ID, 批量下载请提供使用“|”分割的视频ID, 例如: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L\r\n或提供符合以下格式对象的数组json字符串\r\n{ key: string, value: { Title?: string, Alias?: string, Author?: string } }\r\n例如: \r\n[{ key: "AeGUIRO2D5vQ6F", value: { Title: "237知更鸟", Alias: "骑着牛儿追织女", Author: "user1528210" } },{ key: "qQsUMJa19LcK3L", value: { Title: "Mika Automotive Extradimensional", Alias: "Temptation’s_Symphony", Author: "temptations_symphony" } }]', externalVideo: "非本站视频", noAvailableVideoSource: "没有可供下载的视频源", videoSourceNotAvailable: "视频源地址不可用", getVideoSourceFailed: "获取视频源失败", downloadFailed: "下载失败!", downloadThisFailed: "未找到可供下载的视频!", pushTaskFailed: "推送下载任务失败!", parsingFailed: "视频信息解析失败!", autoFollowFailed: "自动关注视频作者失败!", autoLikeFailed: "自动点赞视频失败!" }; var en_default = { appName: "Iwara Download Tool", language: "Language: ", downloadPriority: "Download Quality: ", downloadPath: "Download Path: ", downloadProxy: "Download Proxy: ", downloadProxyUsername: "Download Proxy Username: ", downloadProxyPassword: "Download Proxy Password: ", aria2Path: "Aria2 RPC: ", aria2Token: "Aria2 Token: ", iwaraDownloaderPath: "IwaraDownloader RPC: ", iwaraDownloaderToken: "IwaraDownloader Token: ", experimentalFeatures: "Experimental Features", enableUnsafeMode: "Unsafe Mode (Use at your own risk)", rename: "Rename", save: "Save", reset: "Reset", ok: "OK", on: "On", off: "Off", delete: "Delete", deleteSucceed: "Deletion successful!", isDebug: "Debug Mode", downloadType: "Download Type", browserDownload: "Browser Download", iwaraDownloaderDownload: "IwaraDownloader Download", autoFollow: "Automatically follow the selected video author", autoLike: "Automatically like the selected videos", addUnlistedAndPrivate: "Force display unlisted and private videos (requires following the author)", parseUnlistedAndPrivate: "Parse recent unlisted and private videos", checkDownloadLink: "Check third-party cloud storage download links", checkPriority: "Check download quality", autoDownloadMetadata: "Auto-download metadata", videoMetadata: "Video Metadata", autoInjectCheckbox: "Automatically inject selection box", autoCopySaveFileName: "Automatically copy the filename generated by rules", configurationIncompatible: "Initialization or configuration file incompatible, please reconfigure!", browserDownloadNotEnabled: "Download feature not enabled!", browserDownloadNotWhitelisted: "Requested file extension not whitelisted!", browserDownloadNotPermitted: "Download feature enabled, but permission not granted!", browserDownloadNotSupported: "Current browser/version does not support download functionality!", browserDownloadNotSucceeded: "Download did not start or failed!", browserDownloadUnknownError: "Unknown error, possibly due to invalid download parameters. Please check if the filename is valid!", browserDownloadTimeout: "Download timed out. Please check your network connection!", variable: "View available variables", downloadTime: "Download Time ", uploadTime: "Upload Time ", example: "Example: ", result: "Result: ", loadingCompleted: "Loading completed", settings: "Open Settings", downloadThis: "Download current video", manualDownload: "Manually specify download", aria2TaskCheck: "Aria2 Task Restart", reverseSelect: "Reverse selection on this page", deselectThis: "Deselect on this page", deselectAll: "Deselect all", selectThis: "Select all on this page", selected: "Selected", downloadSelected: "Download selected", downloadingSelected: "Downloading selected, please wait...", injectCheckbox: "Toggle selection box", configError: "There is an error in the script configuration. Please modify.", alreadyKnowHowToUse: "I already know how to use it!!!", notice: [ "Loading Complete", { nodeType: "br" }, "Notice: ", { nodeType: "br" }, "Optimized notification display module, smoother animations (rewrote Toastify JS)" ], useHelpForBase: "Please read the usage guide carefully!", useHelpForInjectCheckbox: 'Enable "%#autoInjectCheckbox#%" for a better experience! Or wait for video cards to load, then click [%#injectCheckbox#%] in the sidebar to enable the selection box.', useHelpForCheckDownloadLink: 'Enabling "%#checkDownloadLink#%" will check the video description and comments before downloading. If third-party cloud storage links are found, a prompt will appear allowing you to visit the video page.', useHelpForManualDownload: [ 'To use manual download, provide the video ID. For batch manual download, use "|" to separate video IDs.', { nodeType: "br" }, "Example: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L", { nodeType: "br" }, "Or provide an array of objects in JSON format matching the following structure:", { nodeType: "br" }, "[ ID: string, { Title?: string, Alias?: string, Author?: string } ]", { nodeType: "br" }, "Example: ", { nodeType: "br" }, `[["AeGUIRO2D5vQ6F", { Title: "237 Robin", Alias: "Riding Cow Chasing Weaving Maiden", Author: "user1528210" }],["qQsUMJa19LcK3L", { Title: "Mika Automotive Extradimensional", Alias: "Temptation's Symphony", Author: "temptations_symphony" }]]` ], useHelpForBugreport: [ "To report bugs or usage issues, please visit: ", { nodeType: "a", childs: "Github", attributes: { href: "https://github.com/dawn-lc/IwaraDownloadTool/" } } ], tryRestartingDownload: "→ Click here to restart download ←", tryReparseDownload: "→ Click here to reparse ←", cdnCacheFinded: "→ Visit MMD Fans Cache Page ←", openVideoLink: "→ Visit Video Page ←", copySucceed: "Copy succeeded!", pushTaskSucceed: "Task pushed successfully!", connectionTest: "Connection Test", settingsCheck: "Settings Check", createTask: "Create Task", downloadPathError: "Download path error!", browserDownloadModeError: "Please enable the browser API download mode in the script manager!", downloadQualityError: "Specified quality download URL not found!", findedDownloadLink: "Possible third-party cloud storage link found!", allCompleted: "All parsing completed!", parsing: "Parsing...", following: "Following", parsingProgress: "Parsing Progress: ", manualDownloadTips: `For individual downloads, input the video ID here. For batch downloads, separate video IDs with "|". Example: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L\r Or provide an array of objects in JSON format matching the following structure:\r { key: string, value: { Title?: string, Alias?: string, Author?: string } }\r Example: \r [{ key: "AeGUIRO2D5vQ6F", value: { Title: "237 Robin", Alias: "Riding Cow Chasing Weaving Maiden", Author: "user1528210" } },{ key: "qQsUMJa19LcK3L", value: { Title: "Mika Automotive Extradimensional", Alias: "Temptation's Symphony", Author: "temptations_symphony" } }]`, externalVideo: "External Video", noAvailableVideoSource: "No available video sources", videoSourceNotAvailable: "Video source URL unavailable", getVideoSourceFailed: "Failed to get video source", downloadFailed: "Download failed!", downloadThisFailed: "No downloadable video found!", pushTaskFailed: "Failed to push download task!", parsingFailed: "Failed to parse video information!", autoFollowFailed: "Failed to auto-follow the video author!", autoLikeFailed: "Failed to auto-like the video!" }; var i18nList = { zh: zh_cn_default, en: en_default }; var DownloadType = (function(DownloadType2) { DownloadType2[DownloadType2["Aria2"] = 0] = "Aria2"; DownloadType2[DownloadType2["IwaraDownloader"] = 1] = "IwaraDownloader"; DownloadType2[DownloadType2["Browser"] = 2] = "Browser"; DownloadType2[DownloadType2["Others"] = 3] = "Others"; return DownloadType2; })({}); var PageType = (function(PageType2) { PageType2["Video"] = "video"; PageType2["Image"] = "image"; PageType2["VideoList"] = "videoList"; PageType2["ImageList"] = "imageList"; PageType2["Forum"] = "forum"; PageType2["ForumSection"] = "forumSection"; PageType2["ForumThread"] = "forumThread"; PageType2["Page"] = "page"; PageType2["Home"] = "home"; PageType2["Profile"] = "profile"; PageType2["Subscriptions"] = "subscriptions"; PageType2["Playlist"] = "playlist"; PageType2["Favorites"] = "favorites"; PageType2["Search"] = "search"; PageType2["Account"] = "account"; return PageType2; })({}); var ToastType = (function(ToastType2) { ToastType2[ToastType2["Log"] = 0] = "Log"; ToastType2[ToastType2["Info"] = 1] = "Info"; ToastType2[ToastType2["Warn"] = 2] = "Warn"; ToastType2[ToastType2["Error"] = 3] = "Error"; return ToastType2; })({}); var MessageType = (function(MessageType2) { MessageType2[MessageType2["Close"] = 0] = "Close"; MessageType2[MessageType2["Request"] = 1] = "Request"; MessageType2[MessageType2["Receive"] = 2] = "Receive"; MessageType2[MessageType2["Set"] = 3] = "Set"; MessageType2[MessageType2["Del"] = 4] = "Del"; return MessageType2; })({}); var VersionState = (function(VersionState2) { VersionState2[VersionState2["Low"] = 0] = "Low"; VersionState2[VersionState2["Equal"] = 1] = "Equal"; VersionState2[VersionState2["High"] = 2] = "High"; return VersionState2; })({}); var originalFetch = unsafeWindow.fetch; var originalHistoryPushState = unsafeWindow.history.pushState; var originalHistoryReplaceState = unsafeWindow.history.replaceState; var originalNodeAppendChild = unsafeWindow.Node.prototype.appendChild; var originalNodeRemoveChild = unsafeWindow.Node.prototype.removeChild; var originalElementRemove = unsafeWindow.Element.prototype.remove; var originalAddEventListener = unsafeWindow.EventTarget.prototype.addEventListener; var originalRemoveEventListener = unsafeWindow.EventTarget.prototype.removeEventListener; var originalStorageSetItem = unsafeWindow.Storage.prototype.setItem; var originalStorageRemoveItem = unsafeWindow.Storage.prototype.removeItem; var originalStorageClear = unsafeWindow.Storage.prototype.clear; var originalConsole = { log: unsafeWindow.console.log.bind(unsafeWindow.console), info: unsafeWindow.console.info.bind(unsafeWindow.console), warn: unsafeWindow.console.warn.bind(unsafeWindow.console), error: unsafeWindow.console.error.bind(unsafeWindow.console), debug: unsafeWindow.console.debug.bind(unsafeWindow.console), trace: unsafeWindow.console.trace.bind(unsafeWindow.console), dir: unsafeWindow.console.dir.bind(unsafeWindow.console), table: unsafeWindow.console.table?.bind(unsafeWindow.console) }; var DEFAULT_CONFIG = { language: "zh_cn", autoFollow: false, autoLike: false, autoCopySaveFileName: false, autoDownloadMetadata: false, enableUnsafeMode: false, experimentalFeatures: false, autoInjectCheckbox: true, checkDownloadLink: false, checkPriority: true, addUnlistedAndPrivate: false, downloadPriority: "Source", downloadType: DownloadType.Others, downloadPath: "/Iwara/%#AUTHOR#%/%#TITLE#%[%#ID#%].mp4", downloadProxy: "", downloadProxyUsername: "", downloadProxyPassword: "", aria2Path: "http://127.0.0.1:6800/jsonrpc", aria2Token: "", iwaraDownloaderPath: "http://127.0.0.1:6800/jsonrpc", iwaraDownloaderToken: "", priority: { "Source": 100, "540": 99, "360": 98, "preview": 1 } }; var Config = class _Config { constructor() { this.language = DEFAULT_CONFIG.language; this.autoFollow = DEFAULT_CONFIG.autoFollow; this.autoLike = DEFAULT_CONFIG.autoLike; this.autoCopySaveFileName = DEFAULT_CONFIG.autoCopySaveFileName; this.experimentalFeatures = DEFAULT_CONFIG.experimentalFeatures; this.enableUnsafeMode = DEFAULT_CONFIG.enableUnsafeMode; this.autoInjectCheckbox = DEFAULT_CONFIG.autoInjectCheckbox; this.checkDownloadLink = DEFAULT_CONFIG.checkDownloadLink; this.checkPriority = DEFAULT_CONFIG.checkPriority; this.addUnlistedAndPrivate = DEFAULT_CONFIG.addUnlistedAndPrivate; this.downloadPriority = DEFAULT_CONFIG.downloadPriority; this.downloadType = DEFAULT_CONFIG.downloadType; this.downloadPath = DEFAULT_CONFIG.downloadPath; this.downloadProxy = DEFAULT_CONFIG.downloadProxy; this.downloadProxyUsername = DEFAULT_CONFIG.downloadProxyUsername; this.downloadProxyPassword = DEFAULT_CONFIG.downloadProxyPassword; this.aria2Path = DEFAULT_CONFIG.aria2Path; this.aria2Token = DEFAULT_CONFIG.aria2Token; this.iwaraDownloaderPath = DEFAULT_CONFIG.iwaraDownloaderPath; this.iwaraDownloaderToken = DEFAULT_CONFIG.iwaraDownloaderToken; this.priority = DEFAULT_CONFIG.priority; this.autoDownloadMetadata = DEFAULT_CONFIG.autoDownloadMetadata; let body = new Proxy(this, { get: function(target, property) { if (property === "configChange") { return target.configChange; } let value = GM_getValue(property, target[property]); if (property === "language") { return _Config.getLanguage(value); } GM_getValue("isDebug") && originalConsole.debug(`[Debug] get: ${property} ${/password/i.test(property) || /token/i.test(property) || /authorization/i.test(property) ? "凭证已隐藏" : stringify(value)}`); return value; }, set: function(target, property, value) { if (property === "configChange") { target.configChange = value; return true; } GM_setValue(property, value); GM_getValue("isDebug") && originalConsole.debug(`[Debug] set: ${property} ${/password/i.test(property) || /token/i.test(property) || /authorization/i.test(property) ? "凭证已隐藏" : stringify(value)}`); if (!isNullOrUndefined(target.configChange)) target.configChange(property); return true; } }); GM_listValues().forEach((value) => { GM_addValueChangeListener(value, (name, old_value, new_value, remote) => { GM_getValue("isDebug") && originalConsole.debug(`[Debug] Config Change Is Remote: ${remote} Change Value: ${name}`); if (remote && !isNullOrUndefined(body.configChange)) body.configChange(name); }); }); return body; } static getLanguage(value) { function formatLanguage(value2) { return value2.replace("-", "_").toLowerCase(); } function getMainLanguage(value2) { return value2.split("_").shift(); } let custom = formatLanguage(value ?? DEFAULT_CONFIG.language); if (!isNullOrUndefined(custom)) { if (!isNullOrUndefined(i18nList[custom])) { return custom; } else { let customMain = getMainLanguage(custom); if (!isNullOrUndefined(i18nList[customMain])) { return customMain; } } } let env = formatLanguage(navigator.language ?? navigator.languages[0] ?? DEFAULT_CONFIG.language); if (!isNullOrUndefined(i18nList[env])) { return env; } else { let main2 = getMainLanguage(env); if (!isNullOrUndefined(i18nList[main2])) { return main2; } } return DEFAULT_CONFIG.language; } static getInstance() { if (isNullOrUndefined(_Config.instance)) _Config.instance = new _Config(); return _Config.instance; } static destroyInstance() { _Config.instance = void 0; } }; var config = Config.getInstance(); var Path = class { constructor(inputPath) { if (inputPath === "") { throw new Error("路径不能为空"); } if (this.isUNC(inputPath)) { throw new Error("不接受UNC路径"); } const detectedType = this.detectPathType(inputPath); this.validatePath(inputPath, detectedType); const normalized = this.normalizePath(inputPath, detectedType); const directory = this.extractDirectory(normalized, detectedType); const fileName = this.extractFileName(normalized, detectedType); const { baseName, extension } = this.extractBaseAndExtension(fileName); this.type = detectedType; this.fullPath = normalized; this.directory = directory; this.fullName = fileName; this.baseName = baseName; this.extension = extension; } isUNC(path) { return path.startsWith("\\\\"); } detectPathType(path) { if (/^[A-Za-z]:[\\/]/.test(path)) { return "Windows"; } if (path.startsWith("/")) { return "Unix"; } return "Relative"; } validatePath(path, type2) { const invalidChars = /[<>:"|?*]/; if (type2 === "Windows") { if (!/^[A-Za-z]:[\\/]/.test(path)) { throw new Error("无效的Windows路径格式"); } const segments = path.split(/[\\/]/); for (let i = 1; i < segments.length; i++) { let segment = segments[i]; let variables = [...segment.matchAll(/%#(.*?)#%/g)].map((match) => { let variable = match[1].split(":"); if (variable.length > 1) { if (invalidChars.test(variable[1])) { throw new Error(`路径变量格式化参数 "${variable[1]}" 含有非法字符`); } } return match[1]; }); for (let index = 0; index < variables.length; index++) { const variable = variables[index]; segment = segment.replaceAll(variable, ""); } if (invalidChars.test(segment)) { throw new Error(`路径段 "${segments[i]}" 含有非法字符`); } } } else if (type2 === "Unix") { if (path.indexOf("\0") !== -1) { throw new Error("路径中包含非法空字符"); } } else if (type2 === "Relative") { if (path.indexOf("\0") !== -1) { throw new Error("路径中包含非法空字符"); } if (invalidChars.test(path)) { throw new Error("路径含有非法字符"); } } } normalizePath(path, type2) { const sep = type2 === "Windows" ? "\\" : "/"; if (type2 === "Windows") { path = path.replace(/\//g, "\\"); path = path.replace(/\\+/g, "\\"); } else { path = path.replace(/\\/g, "/"); path = path.replace(/\/+/g, "/"); } let segments; if (type2 === "Windows") { segments = path.split("\\"); } else { segments = path.split("/"); } let isAbsolute = false; let prefix = ""; if (type2 === "Windows") { if (/^[A-Za-z]:$/.test(segments[0])) { isAbsolute = true; prefix = segments[0]; segments = segments.slice(1); } } else if (type2 === "Unix") { if (path.startsWith("/")) { isAbsolute = true; if (segments[0] === "") { segments = segments.slice(1); } } } else { isAbsolute = false; } const resolvedSegments = this.resolveSegments(segments, isAbsolute); let normalized = ""; if (type2 === "Windows") { normalized = prefix ? prefix + sep + resolvedSegments.join(sep) : resolvedSegments.join(sep); if (prefix && normalized === prefix) { normalized += sep; } } else if (type2 === "Unix") { normalized = (isAbsolute ? sep : "") + resolvedSegments.join(sep); if (isAbsolute && normalized === "") { normalized = sep; } } else { normalized = resolvedSegments.join(sep); } return normalized; } resolveSegments(segments, isAbsolute) { const stack = []; for (const segment of segments) { if (segment === "" || segment === ".") continue; if (segment === "..") { if (stack.length > 0 && stack[stack.length - 1] !== "..") { stack.pop(); } else { if (isAbsolute) { throw new Error("绝对路径不能越界"); } else { stack.push(".."); } } } else { stack.push(segment); } } return stack; } extractDirectory(path, type2) { const sep = type2 === "Windows" ? "\\" : "/"; if (type2 === "Windows" && /^[A-Za-z]:\\$/.test(path)) { return path; } if (type2 === "Unix" && path === "/") { return path; } const lastIndex = path.lastIndexOf(sep); return lastIndex === -1 ? "" : path.substring(0, lastIndex); } extractFileName(path, type2) { const sep = type2 === "Windows" ? "\\" : "/"; const lastIndex = path.lastIndexOf(sep); return lastIndex === -1 ? path : path.substring(lastIndex + 1); } extractBaseAndExtension(fileName) { const lastDot = fileName.lastIndexOf("."); if (lastDot <= 0) { return { baseName: fileName, extension: "" }; } const baseName = fileName.substring(0, lastDot); const extension = fileName.substring(lastDot + 1); return { baseName, extension }; } }; var Version = class _Version { constructor(versionString) { if (!versionString || typeof versionString !== "string") { throw new Error("Invalid version string"); } const [version, preRelease, buildMetadata] = versionString.split(/[-+]/); const versionParts = version.split(".").map(Number); if (versionParts.some(isNaN)) { throw new Error("Version string contains invalid numbers"); } this.major = versionParts[0] || 0; this.minor = versionParts.length > 1 ? versionParts[1] : 0; this.patch = versionParts.length > 2 ? versionParts[2] : 0; this.preRelease = preRelease ? preRelease.split(".") : []; this.buildMetadata = buildMetadata || ""; } static compareValues(a, b) { if (a < b) return VersionState.Low; if (a > b) return VersionState.High; return VersionState.Equal; } compare(other) { let state = _Version.compareValues(this.major, other.major); if (state !== VersionState.Equal) return state; state = _Version.compareValues(this.minor, other.minor); if (state !== VersionState.Equal) return state; state = _Version.compareValues(this.patch, other.patch); if (state !== VersionState.Equal) return state; for (let i = 0; i < Math.max(this.preRelease.length, other.preRelease.length); i++) { const pre1 = this.preRelease[i] ?? ""; const pre2 = other.preRelease[i] ?? ""; state = _Version.compareValues(isNaN(+pre1) ? pre1 : +pre1, isNaN(+pre2) ? pre2 : +pre2); if (state !== VersionState.Equal) return state; } return VersionState.Equal; } toString() { const version = `${this.major}.${this.minor}.${this.patch}`; const preRelease = this.preRelease.length ? `-${this.preRelease.join(".")}` : ""; const buildMetadata = this.buildMetadata ? `+${this.buildMetadata}` : ""; return `${version}${preRelease}${buildMetadata}`; } }; var Dictionary = class extends Map { constructor(data = []) { super(data); } toArray() { return Array.from(this); } keysArray() { return Array.from(this.keys()); } valuesArray() { return Array.from(this.values()); } }; var VCSyncDictionary = class _VCSyncDictionary extends Dictionary { constructor(channelName, initial = []) { super(initial.length ? initial : void 0); this.channelName = channelName; this.id = UUID(); this.vectorClock = { [this.id]: 0 }; this.keyWallClock = new Map(); const now = Date.now(); for (const [k] of initial) { this.keyWallClock.set(k, now); } this.channel = new BroadcastChannel(channelName); this.channel.onmessage = ({ data: msg }) => this.handleMessage(msg); this.channel.postMessage({ type: "sync", id: this.id, vectorClock: this.vectorClock, wallClock: Date.now() }); } incrementVC() { this.vectorClock[this.id] = (this.vectorClock[this.id] ?? 0) + 1; } set(key, value) { this.incrementVC(); const wallClock = Date.now(); super.set(key, value); this.keyWallClock.set(key, wallClock); this.channel.postMessage({ type: "set", key, value, id: this.id, vectorClock: { ...this.vectorClock }, wallClock }); this.onSet?.(key, value); return this; } delete(key) { this.incrementVC(); const wallClock = Date.now(); const existed = super.delete(key); if (existed) { this.keyWallClock.set(key, wallClock); this.channel.postMessage({ type: "delete", key, id: this.id, vectorClock: { ...this.vectorClock }, wallClock }); this.onDel?.(key); } return existed; } clear() { this.incrementVC(); const wallClock = Date.now(); super.clear(); this.keyWallClock.clear(); this.channel.postMessage({ type: "state", state: super.toArray(), id: this.id, vectorClock: { ...this.vectorClock }, wallClock }); this.onSync?.(); } handleMessage(msg) { if (msg.id === this.id) return; const cmp2 = compareVC(msg.vectorClock, this.vectorClock); if (cmp2 === "before") { if (msg.type === "sync") { this.channel.postMessage({ type: "state", state: super.toArray(), id: this.id, vectorClock: { ...this.vectorClock }, wallClock: Date.now() }); } return; } this.vectorClock = mergeVC(this.vectorClock, msg.vectorClock); switch (msg.type) { case "state": super.clear(); this.keyWallClock.clear(); const now = Date.now(); for (const [key, value] of msg.state) { super.set(key, value); this.keyWallClock.set(key, now); } this.onSync?.(); break; case "set": { const { key, value, wallClock } = msg; const localWallClock = this.keyWallClock.get(key) ?? 0; if (cmp2 === "after" || cmp2 === "concurrent" && wallClock > localWallClock) { super.set(key, value); this.keyWallClock.set(key, wallClock); this.onSet?.(key, value); } break; } case "delete": { const { key, wallClock } = msg; const localWallClock = this.keyWallClock.get(key) ?? 0; if (cmp2 === "after" || cmp2 === "concurrent" && wallClock > localWallClock) { if (super.delete(key)) { this.keyWallClock.set(key, wallClock); this.onDel?.(key); } } break; } } } save() { const obj = { data: super.toArray(), vectorClock: this.vectorClock, keyWallClock: Array.from(this.keyWallClock.entries()), id: this.id }; GM_setValue(this.channelName, obj); } static load(channelName) { const obj = GM_getValue(channelName, void 0); if (!obj) return void 0; const dict = new _VCSyncDictionary(channelName, obj.data); dict.vectorClock = obj.vectorClock || {}; dict.keyWallClock = new Map(obj.keyWallClock || []); dict.id = obj.id || UUID(); return dict; } }; var SyncDictionary = class extends Dictionary { constructor(channelName, initial = []) { const hasInitial = prune(initial).any(); super(hasInitial ? initial : void 0); this.timestamp = hasInitial ? Date.now() : 0; this.lifetime = hasInitial ? performance.now() : 0; this.id = UUID(); this.channel = new BroadcastChannel(channelName); this.channel.onmessage = ({ data: msg }) => this.handleMessage(msg); this.channel.postMessage({ type: "sync", id: this.id, timestamp: this.timestamp, lifetime: this.lifetime }); } setTimestamp(timestamp) { this.timestamp = timestamp ?? Date.now(); this.lifetime = performance.now(); } set(key, value) { this.setTimestamp(); super.set(key, value); this.channel.postMessage({ type: "set", key, value, timestamp: this.timestamp, lifetime: this.lifetime, id: this.id }); this.onSet?.(key, value); return this; } delete(key) { this.setTimestamp(); const existed = super.delete(key); if (existed) { this.onDel?.(key); this.channel.postMessage({ type: "delete", key, timestamp: this.timestamp, lifetime: this.lifetime, id: this.id }); } return existed; } clear() { this.setTimestamp(); super.clear(); this.channel.postMessage({ timestamp: this.timestamp, lifetime: this.lifetime, id: this.id, type: "state", state: super.toArray() }); this.onSync?.(); } handleMessage(msg) { if (msg.id === this.id) return; if (msg.type === "sync") { this.channel.postMessage({ timestamp: this.timestamp, lifetime: this.lifetime, id: this.id, type: "state", state: super.toArray() }); return; } if (msg.timestamp === this.timestamp && msg.lifetime === this.lifetime) return; if (msg.timestamp < this.timestamp || msg.lifetime < this.lifetime) return; switch (msg.type) { case "state": { super.clear(); for (let index = 0; index < msg.state.length; index++) { const [key, value] = msg.state[index]; super.set(key, value); } this.setTimestamp(msg.timestamp); this.onSync?.(); break; } case "set": { const { key, value } = msg; super.set(key, value); this.setTimestamp(msg.timestamp); this.onSet?.(key, value); break; } case "delete": { const { key } = msg; if (super.delete(key)) { this.setTimestamp(msg.timestamp); this.onDel?.(key); } break; } } } }; var MultiPage = class { constructor() { this.pageId = UUID(); GM_saveTab({ id: this.pageId }); this.channel = new BroadcastChannel("page-status-channel"); this.channel.onmessage = (event) => this.handleMessage(event.data); this.channel.postMessage({ type: "join", id: this.pageId }); this.beforeUnloadHandler = () => { this.channel.postMessage({ type: "leave", id: this.pageId }); originalRemoveEventListener.call(unsafeWindow.document, "beforeunload", this.beforeUnloadHandler); }; originalAddEventListener.call(unsafeWindow.document, "beforeunload", this.beforeUnloadHandler); } suicide() { this.channel.postMessage({ type: "suicide", id: this.pageId }); } handleMessage(message) { switch (message.type) { case "suicide": if (this.pageId !== message.id) unsafeWindow.close(); break; case "join": this.onPageJoin?.(message.id); break; case "leave": this.onPageLeave?.(message.id); GM_getTabs((tabs) => { if (Object.keys(tabs).length > 1) return; this.onLastPage?.(); }); break; } } }; var _global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : global; var keys = Object.keys; var isArray2 = Array.isArray; if (typeof Promise !== "undefined" && !_global.Promise) { _global.Promise = Promise; } function extend(obj, extension) { if (typeof extension !== "object") return obj; keys(extension).forEach(function(key) { obj[key] = extension[key]; }); return obj; } var getProto = Object.getPrototypeOf; var _hasOwn = {}.hasOwnProperty; function hasOwn(obj, prop) { return _hasOwn.call(obj, prop); } function props(proto, extension) { if (typeof extension === "function") extension = extension(getProto(proto)); (typeof Reflect === "undefined" ? keys : Reflect.ownKeys)(extension).forEach((key) => { setProp(proto, key, extension[key]); }); } var defineProperty = Object.defineProperty; function setProp(obj, prop, functionOrGetSet, options) { defineProperty(obj, prop, extend(functionOrGetSet && hasOwn(functionOrGetSet, "get") && typeof functionOrGetSet.get === "function" ? { get: functionOrGetSet.get, set: functionOrGetSet.set, configurable: true } : { value: functionOrGetSet, configurable: true, writable: true }, options)); } function derive(Child) { return { from: function(Parent) { Child.prototype = Object.create(Parent.prototype); setProp(Child.prototype, "constructor", Child); return { extend: props.bind(null, Child.prototype) }; } }; } var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; function getPropertyDescriptor(obj, prop) { const pd = getOwnPropertyDescriptor(obj, prop); let proto; return pd || (proto = getProto(obj)) && getPropertyDescriptor(proto, prop); } var _slice = [].slice; function slice(args, start, end) { return _slice.call(args, start, end); } function override(origFunc, overridedFactory) { return overridedFactory(origFunc); } function assert(b) { if (!b) throw new Error("Assertion Failed"); } function asap$1(fn) { if (_global.setImmediate) setImmediate(fn); else setTimeout(fn, 0); } function arrayToObject(array, extractor) { return array.reduce((result, item, i) => { var nameAndValue = extractor(item, i); if (nameAndValue) result[nameAndValue[0]] = nameAndValue[1]; return result; }, {}); } function tryCatch(fn, onerror, args) { try { fn.apply(null, args); } catch (ex) { onerror && onerror(ex); } } function getByKeyPath(obj, keyPath) { if (typeof keyPath === "string" && hasOwn(obj, keyPath)) return obj[keyPath]; if (!keyPath) return obj; if (typeof keyPath !== "string") { var rv = []; for (var i = 0, l = keyPath.length; i < l; ++i) { var val = getByKeyPath(obj, keyPath[i]); rv.push(val); } return rv; } var period = keyPath.indexOf("."); if (period !== -1) { var innerObj = obj[keyPath.substr(0, period)]; return innerObj == null ? void 0 : getByKeyPath(innerObj, keyPath.substr(period + 1)); } return void 0; } function setByKeyPath(obj, keyPath, value) { if (!obj || keyPath === void 0) return; if ("isFrozen" in Object && Object.isFrozen(obj)) return; if (typeof keyPath !== "string" && "length" in keyPath) { assert(typeof value !== "string" && "length" in value); for (var i = 0, l = keyPath.length; i < l; ++i) { setByKeyPath(obj, keyPath[i], value[i]); } } else { var period = keyPath.indexOf("."); if (period !== -1) { var currentKeyPath = keyPath.substr(0, period); var remainingKeyPath = keyPath.substr(period + 1); if (remainingKeyPath === "") if (value === void 0) { if (isArray2(obj) && !isNaN(parseInt(currentKeyPath))) obj.splice(currentKeyPath, 1); else delete obj[currentKeyPath]; } else obj[currentKeyPath] = value; else { var innerObj = obj[currentKeyPath]; if (!innerObj || !hasOwn(obj, currentKeyPath)) innerObj = obj[currentKeyPath] = {}; setByKeyPath(innerObj, remainingKeyPath, value); } } else { if (value === void 0) { if (isArray2(obj) && !isNaN(parseInt(keyPath))) obj.splice(keyPath, 1); else delete obj[keyPath]; } else obj[keyPath] = value; } } } function delByKeyPath(obj, keyPath) { if (typeof keyPath === "string") setByKeyPath(obj, keyPath, void 0); else if ("length" in keyPath) [].map.call(keyPath, function(kp) { setByKeyPath(obj, kp, void 0); }); } function shallowClone(obj) { var rv = {}; for (var m in obj) { if (hasOwn(obj, m)) rv[m] = obj[m]; } return rv; } var concat = [].concat; function flatten(a) { return concat.apply([], a); } var intrinsicTypeNames = "BigUint64Array,BigInt64Array,Array,Boolean,String,Date,RegExp,Blob,File,FileList,FileSystemFileHandle,FileSystemDirectoryHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey".split(",").concat(flatten([8, 16, 32, 64].map((num) => ["Int", "Uint", "Float"].map((t) => t + num + "Array")))).filter((t) => _global[t]); var intrinsicTypes = intrinsicTypeNames.map((t) => _global[t]); arrayToObject(intrinsicTypeNames, (x) => [x, true]); var circularRefs = null; function deepClone(any) { circularRefs = typeof WeakMap !== "undefined" && new WeakMap(); const rv = innerDeepClone(any); circularRefs = null; return rv; } function innerDeepClone(any) { if (!any || typeof any !== "object") return any; let rv = circularRefs && circularRefs.get(any); if (rv) return rv; if (isArray2(any)) { rv = []; circularRefs && circularRefs.set(any, rv); for (var i = 0, l = any.length; i < l; ++i) { rv.push(innerDeepClone(any[i])); } } else if (intrinsicTypes.indexOf(any.constructor) >= 0) { rv = any; } else { const proto = getProto(any); rv = proto === Object.prototype ? {} : Object.create(proto); circularRefs && circularRefs.set(any, rv); for (var prop in any) { if (hasOwn(any, prop)) { rv[prop] = innerDeepClone(any[prop]); } } } return rv; } var { toString } = {}; function toStringTag(o) { return toString.call(o).slice(8, -1); } var iteratorSymbol = typeof Symbol !== "undefined" ? Symbol.iterator : "@@iterator"; var getIteratorOf = typeof iteratorSymbol === "symbol" ? function(x) { var i; return x != null && (i = x[iteratorSymbol]) && i.apply(x); } : function() { return null; }; var NO_CHAR_ARRAY = {}; function getArrayOf(arrayLike) { var i, a, x, it; if (arguments.length === 1) { if (isArray2(arrayLike)) return arrayLike.slice(); if (this === NO_CHAR_ARRAY && typeof arrayLike === "string") return [arrayLike]; if (it = getIteratorOf(arrayLike)) { a = []; while (x = it.next(), !x.done) a.push(x.value); return a; } if (arrayLike == null) return [arrayLike]; i = arrayLike.length; if (typeof i === "number") { a = new Array(i); while (i--) a[i] = arrayLike[i]; return a; } return [arrayLike]; } i = arguments.length; a = new Array(i); while (i--) a[i] = arguments[i]; return a; } var isAsyncFunction = typeof Symbol !== "undefined" ? (fn) => fn[Symbol.toStringTag] === "AsyncFunction" : () => false; var debug = typeof location !== "undefined" && /^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href); function setDebug(value, filter) { debug = value; libraryFilter = filter; } var libraryFilter = () => true; var NEEDS_THROW_FOR_STACK = !new Error("").stack; function getErrorWithStack() { if (NEEDS_THROW_FOR_STACK) try { getErrorWithStack.arguments; throw new Error(); } catch (e) { return e; } return new Error(); } function prettyStack(exception, numIgnoredFrames) { var stack = exception.stack; if (!stack) return ""; numIgnoredFrames = numIgnoredFrames || 0; if (stack.indexOf(exception.name) === 0) numIgnoredFrames += (exception.name + exception.message).split("\n").length; return stack.split("\n").slice(numIgnoredFrames).filter(libraryFilter).map((frame) => "\n" + frame).join(""); } var dexieErrorNames = [ "Modify", "Bulk", "OpenFailed", "VersionChange", "Schema", "Upgrade", "InvalidTable", "MissingAPI", "NoSuchDatabase", "InvalidArgument", "SubTransaction", "Unsupported", "Internal", "DatabaseClosed", "PrematureCommit", "ForeignAwait" ]; var idbDomErrorNames = [ "Unknown", "Constraint", "Data", "TransactionInactive", "ReadOnly", "Version", "NotFound", "InvalidState", "InvalidAccess", "Abort", "Timeout", "QuotaExceeded", "Syntax", "DataClone" ]; var errorList = dexieErrorNames.concat(idbDomErrorNames); var defaultTexts = { VersionChanged: "Database version changed by other database connection", DatabaseClosed: "Database has been closed", Abort: "Transaction aborted", TransactionInactive: "Transaction has already completed or failed", MissingAPI: "IndexedDB API missing. Please visit https://tinyurl.com/y2uuvskb" }; function DexieError(name, msg) { this._e = getErrorWithStack(); this.name = name; this.message = msg; } derive(DexieError).from(Error).extend({ stack: { get: function() { return this._stack || (this._stack = this.name + ": " + this.message + prettyStack(this._e, 2)); } }, toString: function() { return this.name + ": " + this.message; } }); function getMultiErrorMessage(msg, failures) { return msg + ". Errors: " + Object.keys(failures).map((key) => failures[key].toString()).filter((v, i, s) => s.indexOf(v) === i).join("\n"); } function ModifyError(msg, failures, successCount, failedKeys) { this._e = getErrorWithStack(); this.failures = failures; this.failedKeys = failedKeys; this.successCount = successCount; this.message = getMultiErrorMessage(msg, failures); } derive(ModifyError).from(DexieError); function BulkError(msg, failures) { this._e = getErrorWithStack(); this.name = "BulkError"; this.failures = Object.keys(failures).map((pos) => failures[pos]); this.failuresByPos = failures; this.message = getMultiErrorMessage(msg, failures); } derive(BulkError).from(DexieError); var errnames = errorList.reduce((obj, name) => (obj[name] = name + "Error", obj), {}); var BaseException = DexieError; var exceptions = errorList.reduce((obj, name) => { var fullName = name + "Error"; function DexieError2(msgOrInner, inner) { this._e = getErrorWithStack(); this.name = fullName; if (!msgOrInner) { this.message = defaultTexts[name] || fullName; this.inner = null; } else if (typeof msgOrInner === "string") { this.message = `${msgOrInner}${!inner ? "" : "\n " + inner}`; this.inner = inner || null; } else if (typeof msgOrInner === "object") { this.message = `${msgOrInner.name} ${msgOrInner.message}`; this.inner = msgOrInner; } } derive(DexieError2).from(BaseException); obj[name] = DexieError2; return obj; }, {}); exceptions.Syntax = SyntaxError; exceptions.Type = TypeError; exceptions.Range = RangeError; var exceptionMap = idbDomErrorNames.reduce((obj, name) => { obj[name + "Error"] = exceptions[name]; return obj; }, {}); function mapError(domError, message) { if (!domError || domError instanceof DexieError || domError instanceof TypeError || domError instanceof SyntaxError || !domError.name || !exceptionMap[domError.name]) return domError; var rv = new exceptionMap[domError.name](message || domError.message, domError); if ("stack" in domError) { setProp(rv, "stack", { get: function() { return this.inner.stack; } }); } return rv; } var fullNameExceptions = errorList.reduce((obj, name) => { if (["Syntax", "Type", "Range"].indexOf(name) === -1) obj[name + "Error"] = exceptions[name]; return obj; }, {}); fullNameExceptions.ModifyError = ModifyError; fullNameExceptions.DexieError = DexieError; fullNameExceptions.BulkError = BulkError; function nop() { } function mirror(val) { return val; } function pureFunctionChain(f1, f2) { if (f1 == null || f1 === mirror) return f2; return function(val) { return f2(f1(val)); }; } function callBoth(on1, on2) { return function() { on1.apply(this, arguments); on2.apply(this, arguments); }; } function hookCreatingChain(f1, f2) { if (f1 === nop) return f2; return function() { var res = f1.apply(this, arguments); if (res !== void 0) arguments[0] = res; var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = null; this.onerror = null; var res2 = f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; return res2 !== void 0 ? res2 : res; }; } function hookDeletingChain(f1, f2) { if (f1 === nop) return f2; return function() { f1.apply(this, arguments); var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = this.onerror = null; f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; }; } function hookUpdatingChain(f1, f2) { if (f1 === nop) return f2; return function(modifications) { var res = f1.apply(this, arguments); extend(modifications, res); var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = null; this.onerror = null; var res2 = f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; return res === void 0 ? res2 === void 0 ? void 0 : res2 : extend(res, res2); }; } function reverseStoppableEventChain(f1, f2) { if (f1 === nop) return f2; return function() { if (f2.apply(this, arguments) === false) return false; return f1.apply(this, arguments); }; } function promisableChain(f1, f2) { if (f1 === nop) return f2; return function() { var res = f1.apply(this, arguments); if (res && typeof res.then === "function") { var thiz = this, i = arguments.length, args = new Array(i); while (i--) args[i] = arguments[i]; return res.then(function() { return f2.apply(thiz, args); }); } return f2.apply(this, arguments); }; } var INTERNAL = {}; var LONG_STACKS_CLIP_LIMIT = 100, MAX_LONG_STACKS = 20, ZONE_ECHO_LIMIT = 100, [resolvedNativePromise, nativePromiseProto, resolvedGlobalPromise] = typeof Promise === "undefined" ? [] : (() => { let globalP = Promise.resolve(); if (typeof crypto === "undefined" || !crypto.subtle) return [globalP, getProto(globalP), globalP]; const nativeP = crypto.subtle.digest("SHA-512", new Uint8Array([0])); return [ nativeP, getProto(nativeP), globalP ]; })(), nativePromiseThen = nativePromiseProto && nativePromiseProto.then; var NativePromise = resolvedNativePromise && resolvedNativePromise.constructor; var patchGlobalPromise = !!resolvedGlobalPromise; var stack_being_generated = false; var schedulePhysicalTick = resolvedGlobalPromise ? () => { resolvedGlobalPromise.then(physicalTick); } : _global.setImmediate ? setImmediate.bind(null, physicalTick) : _global.MutationObserver ? () => { var hiddenDiv = document.createElement("div"); new MutationObserver(() => { physicalTick(); hiddenDiv = null; }).observe(hiddenDiv, { attributes: true }); hiddenDiv.setAttribute("i", "1"); } : () => { setTimeout(physicalTick, 0); }; var asap = function(callback, args) { microtickQueue.push([callback, args]); if (needsNewPhysicalTick) { schedulePhysicalTick(); needsNewPhysicalTick = false; } }; var isOutsideMicroTick = true, needsNewPhysicalTick = true, unhandledErrors = [], rejectingErrors = [], currentFulfiller = null, rejectionMapper = mirror; var globalPSD = { id: "global", global: true, ref: 0, unhandleds: [], onunhandled: globalError, pgp: false, env: {}, finalize: function() { this.unhandleds.forEach((uh) => { try { globalError(uh[0], uh[1]); } catch (e) { } }); } }; var PSD = globalPSD; var microtickQueue = []; var numScheduledCalls = 0; var tickFinalizers = []; function DexiePromise(fn) { if (typeof this !== "object") throw new TypeError("Promises must be constructed via new"); this._listeners = []; this.onuncatched = nop; this._lib = false; var psd = this._PSD = PSD; if (debug) { this._stackHolder = getErrorWithStack(); this._prev = null; this._numPrev = 0; } if (typeof fn !== "function") { if (fn !== INTERNAL) throw new TypeError("Not a function"); this._state = arguments[1]; this._value = arguments[2]; if (this._state === false) handleRejection(this, this._value); return; } this._state = null; this._value = null; ++psd.ref; executePromiseTask(this, fn); } var thenProp = { get: function() { var psd = PSD, microTaskId = totalEchoes; function then(onFulfilled, onRejected) { var possibleAwait = !psd.global && (psd !== PSD || microTaskId !== totalEchoes); const cleanup = possibleAwait && !decrementExpectedAwaits(); var rv = new DexiePromise((resolve, reject) => { propagateToListener(this, new Listener(nativeAwaitCompatibleWrap(onFulfilled, psd, possibleAwait, cleanup), nativeAwaitCompatibleWrap(onRejected, psd, possibleAwait, cleanup), resolve, reject, psd)); }); debug && linkToPreviousPromise(rv, this); return rv; } then.prototype = INTERNAL; return then; }, set: function(value) { setProp(this, "then", value && value.prototype === INTERNAL ? thenProp : { get: function() { return value; }, set: thenProp.set }); } }; props(DexiePromise.prototype, { then: thenProp, _then: function(onFulfilled, onRejected) { propagateToListener(this, new Listener(null, null, onFulfilled, onRejected, PSD)); }, catch: function(onRejected) { if (arguments.length === 1) return this.then(null, onRejected); var type2 = arguments[0], handler = arguments[1]; return typeof type2 === "function" ? this.then(null, (err) => err instanceof type2 ? handler(err) : PromiseReject(err)) : this.then(null, (err) => err && err.name === type2 ? handler(err) : PromiseReject(err)); }, finally: function(onFinally) { return this.then((value) => { onFinally(); return value; }, (err) => { onFinally(); return PromiseReject(err); }); }, stack: { get: function() { if (this._stack) return this._stack; try { stack_being_generated = true; var stacks = getStack(this, [], MAX_LONG_STACKS); var stack = stacks.join("\nFrom previous: "); if (this._state !== null) this._stack = stack; return stack; } finally { stack_being_generated = false; } } }, timeout: function(ms, msg) { return ms < Infinity ? new DexiePromise((resolve, reject) => { var handle = setTimeout(() => reject(new exceptions.Timeout(msg)), ms); this.then(resolve, reject).finally(clearTimeout.bind(null, handle)); }) : this; } }); if (typeof Symbol !== "undefined" && Symbol.toStringTag) setProp(DexiePromise.prototype, Symbol.toStringTag, "Dexie.Promise"); globalPSD.env = snapShot(); function Listener(onFulfilled, onRejected, resolve, reject, zone) { this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null; this.onRejected = typeof onRejected === "function" ? onRejected : null; this.resolve = resolve; this.reject = reject; this.psd = zone; } props(DexiePromise, { all: function() { var values = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise(function(resolve, reject) { if (values.length === 0) resolve([]); var remaining = values.length; values.forEach((a, i) => DexiePromise.resolve(a).then((x) => { values[i] = x; if (!--remaining) resolve(values); }, reject)); }); }, resolve: (value) => { if (value instanceof DexiePromise) return value; if (value && typeof value.then === "function") return new DexiePromise((resolve, reject) => { value.then(resolve, reject); }); var rv = new DexiePromise(INTERNAL, true, value); linkToPreviousPromise(rv, currentFulfiller); return rv; }, reject: PromiseReject, race: function() { var values = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise((resolve, reject) => { values.map((value) => DexiePromise.resolve(value).then(resolve, reject)); }); }, PSD: { get: () => PSD, set: (value) => PSD = value }, totalEchoes: { get: () => totalEchoes }, newPSD: newScope, usePSD, scheduler: { get: () => asap, set: (value) => { asap = value; } }, rejectionMapper: { get: () => rejectionMapper, set: (value) => { rejectionMapper = value; } }, follow: (fn, zoneProps) => { return new DexiePromise((resolve, reject) => { return newScope((resolve2, reject2) => { var psd = PSD; psd.unhandleds = []; psd.onunhandled = reject2; psd.finalize = callBoth(function() { run_at_end_of_this_or_next_physical_tick(() => { this.unhandleds.length === 0 ? resolve2() : reject2(this.unhandleds[0]); }); }, psd.finalize); fn(); }, zoneProps, resolve, reject); }); } }); if (NativePromise) { if (NativePromise.allSettled) setProp(DexiePromise, "allSettled", function() { const possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise((resolve) => { if (possiblePromises.length === 0) resolve([]); let remaining = possiblePromises.length; const results = new Array(remaining); possiblePromises.forEach((p, i) => DexiePromise.resolve(p).then((value) => results[i] = { status: "fulfilled", value }, (reason) => results[i] = { status: "rejected", reason }).then(() => --remaining || resolve(results))); }); }); if (NativePromise.any && typeof AggregateError !== "undefined") setProp(DexiePromise, "any", function() { const possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise((resolve, reject) => { if (possiblePromises.length === 0) reject(new AggregateError([])); let remaining = possiblePromises.length; const failures = new Array(remaining); possiblePromises.forEach((p, i) => DexiePromise.resolve(p).then((value) => resolve(value), (failure) => { failures[i] = failure; if (!--remaining) reject(new AggregateError(failures)); })); }); }); } function executePromiseTask(promise, fn) { try { fn((value) => { if (promise._state !== null) return; if (value === promise) throw new TypeError("A promise cannot be resolved with itself."); var shouldExecuteTick = promise._lib && beginMicroTickScope(); if (value && typeof value.then === "function") { executePromiseTask(promise, (resolve, reject) => { value instanceof DexiePromise ? value._then(resolve, reject) : value.then(resolve, reject); }); } else { promise._state = true; promise._value = value; propagateAllListeners(promise); } if (shouldExecuteTick) endMicroTickScope(); }, handleRejection.bind(null, promise)); } catch (ex) { handleRejection(promise, ex); } } function handleRejection(promise, reason) { rejectingErrors.push(reason); if (promise._state !== null) return; var shouldExecuteTick = promise._lib && beginMicroTickScope(); reason = rejectionMapper(reason); promise._state = false; promise._value = reason; debug && reason !== null && typeof reason === "object" && !reason._promise && tryCatch(() => { var origProp = getPropertyDescriptor(reason, "stack"); reason._promise = promise; setProp(reason, "stack", { get: () => stack_being_generated ? origProp && (origProp.get ? origProp.get.apply(reason) : origProp.value) : promise.stack }); }); addPossiblyUnhandledError(promise); propagateAllListeners(promise); if (shouldExecuteTick) endMicroTickScope(); } function propagateAllListeners(promise) { var listeners = promise._listeners; promise._listeners = []; for (var i = 0, len = listeners.length; i < len; ++i) { propagateToListener(promise, listeners[i]); } var psd = promise._PSD; --psd.ref || psd.finalize(); if (numScheduledCalls === 0) { ++numScheduledCalls; asap(() => { if (--numScheduledCalls === 0) finalizePhysicalTick(); }, []); } } function propagateToListener(promise, listener) { if (promise._state === null) { promise._listeners.push(listener); return; } var cb = promise._state ? listener.onFulfilled : listener.onRejected; if (cb === null) { return (promise._state ? listener.resolve : listener.reject)(promise._value); } ++listener.psd.ref; ++numScheduledCalls; asap(callListener, [cb, promise, listener]); } function callListener(cb, promise, listener) { try { currentFulfiller = promise; var ret, value = promise._value; if (promise._state) { ret = cb(value); } else { if (rejectingErrors.length) rejectingErrors = []; ret = cb(value); if (rejectingErrors.indexOf(value) === -1) markErrorAsHandled(promise); } listener.resolve(ret); } catch (e) { listener.reject(e); } finally { currentFulfiller = null; if (--numScheduledCalls === 0) finalizePhysicalTick(); --listener.psd.ref || listener.psd.finalize(); } } function getStack(promise, stacks, limit) { if (stacks.length === limit) return stacks; var stack = ""; if (promise._state === false) { var failure = promise._value, errorName, message; if (failure != null) { errorName = failure.name || "Error"; message = failure.message || failure; stack = prettyStack(failure, 0); } else { errorName = failure; message = ""; } stacks.push(errorName + (message ? ": " + message : "") + stack); } if (debug) { stack = prettyStack(promise._stackHolder, 2); if (stack && stacks.indexOf(stack) === -1) stacks.push(stack); if (promise._prev) getStack(promise._prev, stacks, limit); } return stacks; } function linkToPreviousPromise(promise, prev) { var numPrev = prev ? prev._numPrev + 1 : 0; if (numPrev < LONG_STACKS_CLIP_LIMIT) { promise._prev = prev; promise._numPrev = numPrev; } } function physicalTick() { beginMicroTickScope() && endMicroTickScope(); } function beginMicroTickScope() { var wasRootExec = isOutsideMicroTick; isOutsideMicroTick = false; needsNewPhysicalTick = false; return wasRootExec; } function endMicroTickScope() { var callbacks, i, l; do { while (microtickQueue.length > 0) { callbacks = microtickQueue; microtickQueue = []; l = callbacks.length; for (i = 0; i < l; ++i) { var item = callbacks[i]; item[0].apply(null, item[1]); } } } while (microtickQueue.length > 0); isOutsideMicroTick = true; needsNewPhysicalTick = true; } function finalizePhysicalTick() { var unhandledErrs = unhandledErrors; unhandledErrors = []; unhandledErrs.forEach((p) => { p._PSD.onunhandled.call(null, p._value, p); }); var finalizers = tickFinalizers.slice(0); var i = finalizers.length; while (i) finalizers[--i](); } function run_at_end_of_this_or_next_physical_tick(fn) { function finalizer() { fn(); tickFinalizers.splice(tickFinalizers.indexOf(finalizer), 1); } tickFinalizers.push(finalizer); ++numScheduledCalls; asap(() => { if (--numScheduledCalls === 0) finalizePhysicalTick(); }, []); } function addPossiblyUnhandledError(promise) { if (!unhandledErrors.some((p) => p._value === promise._value)) unhandledErrors.push(promise); } function markErrorAsHandled(promise) { var i = unhandledErrors.length; while (i) if (unhandledErrors[--i]._value === promise._value) { unhandledErrors.splice(i, 1); return; } } function PromiseReject(reason) { return new DexiePromise(INTERNAL, false, reason); } function wrap(fn, errorCatcher) { var psd = PSD; return function() { var wasRootExec = beginMicroTickScope(), outerScope = PSD; try { switchToZone(psd, true); return fn.apply(this, arguments); } catch (e) { errorCatcher && errorCatcher(e); } finally { switchToZone(outerScope, false); if (wasRootExec) endMicroTickScope(); } }; } var task = { awaits: 0, echoes: 0, id: 0 }; var taskCounter = 0; var zoneStack = []; var zoneEchoes = 0; var totalEchoes = 0; var zone_id_counter = 0; function newScope(fn, props2, a1, a2) { var parent = PSD, psd = Object.create(parent); psd.parent = parent; psd.ref = 0; psd.global = false; psd.id = ++zone_id_counter; var globalEnv = globalPSD.env; psd.env = patchGlobalPromise ? { Promise: DexiePromise, PromiseProp: { value: DexiePromise, configurable: true, writable: true }, all: DexiePromise.all, race: DexiePromise.race, allSettled: DexiePromise.allSettled, any: DexiePromise.any, resolve: DexiePromise.resolve, reject: DexiePromise.reject, nthen: getPatchedPromiseThen(globalEnv.nthen, psd), gthen: getPatchedPromiseThen(globalEnv.gthen, psd) } : {}; if (props2) extend(psd, props2); ++parent.ref; psd.finalize = function() { --this.parent.ref || this.parent.finalize(); }; var rv = usePSD(psd, fn, a1, a2); if (psd.ref === 0) psd.finalize(); return rv; } function incrementExpectedAwaits() { if (!task.id) task.id = ++taskCounter; ++task.awaits; task.echoes += ZONE_ECHO_LIMIT; return task.id; } function decrementExpectedAwaits() { if (!task.awaits) return false; if (--task.awaits === 0) task.id = 0; task.echoes = task.awaits * ZONE_ECHO_LIMIT; return true; } if (("" + nativePromiseThen).indexOf("[native code]") === -1) { incrementExpectedAwaits = decrementExpectedAwaits = nop; } function onPossibleParallellAsync(possiblePromise) { if (task.echoes && possiblePromise && possiblePromise.constructor === NativePromise) { incrementExpectedAwaits(); return possiblePromise.then((x) => { decrementExpectedAwaits(); return x; }, (e) => { decrementExpectedAwaits(); return rejection(e); }); } return possiblePromise; } function zoneEnterEcho(targetZone) { ++totalEchoes; if (!task.echoes || --task.echoes === 0) { task.echoes = task.id = 0; } zoneStack.push(PSD); switchToZone(targetZone, true); } function zoneLeaveEcho() { var zone = zoneStack[zoneStack.length - 1]; zoneStack.pop(); switchToZone(zone, false); } function switchToZone(targetZone, bEnteringZone) { var currentZone = PSD; if (bEnteringZone ? task.echoes && (!zoneEchoes++ || targetZone !== PSD) : zoneEchoes && (!--zoneEchoes || targetZone !== PSD)) { enqueueNativeMicroTask(bEnteringZone ? zoneEnterEcho.bind(null, targetZone) : zoneLeaveEcho); } if (targetZone === PSD) return; PSD = targetZone; if (currentZone === globalPSD) globalPSD.env = snapShot(); if (patchGlobalPromise) { var GlobalPromise = globalPSD.env.Promise; var targetEnv = targetZone.env; nativePromiseProto.then = targetEnv.nthen; GlobalPromise.prototype.then = targetEnv.gthen; if (currentZone.global || targetZone.global) { Object.defineProperty(_global, "Promise", targetEnv.PromiseProp); GlobalPromise.all = targetEnv.all; GlobalPromise.race = targetEnv.race; GlobalPromise.resolve = targetEnv.resolve; GlobalPromise.reject = targetEnv.reject; if (targetEnv.allSettled) GlobalPromise.allSettled = targetEnv.allSettled; if (targetEnv.any) GlobalPromise.any = targetEnv.any; } } } function snapShot() { var GlobalPromise = _global.Promise; return patchGlobalPromise ? { Promise: GlobalPromise, PromiseProp: Object.getOwnPropertyDescriptor(_global, "Promise"), all: GlobalPromise.all, race: GlobalPromise.race, allSettled: GlobalPromise.allSettled, any: GlobalPromise.any, resolve: GlobalPromise.resolve, reject: GlobalPromise.reject, nthen: nativePromiseProto.then, gthen: GlobalPromise.prototype.then } : {}; } function usePSD(psd, fn, a1, a2, a3) { var outerScope = PSD; try { switchToZone(psd, true); return fn(a1, a2, a3); } finally { switchToZone(outerScope, false); } } function enqueueNativeMicroTask(job) { nativePromiseThen.call(resolvedNativePromise, job); } function nativeAwaitCompatibleWrap(fn, zone, possibleAwait, cleanup) { return typeof fn !== "function" ? fn : function() { var outerZone = PSD; if (possibleAwait) incrementExpectedAwaits(); switchToZone(zone, true); try { return fn.apply(this, arguments); } finally { switchToZone(outerZone, false); if (cleanup) enqueueNativeMicroTask(decrementExpectedAwaits); } }; } function getPatchedPromiseThen(origThen, zone) { return function(onResolved, onRejected) { return origThen.call(this, nativeAwaitCompatibleWrap(onResolved, zone), nativeAwaitCompatibleWrap(onRejected, zone)); }; } var UNHANDLEDREJECTION = "unhandledrejection"; function globalError(err, promise) { var rv; try { rv = promise.onuncatched(err); } catch (e) { } if (rv !== false) try { var event, eventData = { promise, reason: err }; if (_global.document && document.createEvent) { event = document.createEvent("Event"); event.initEvent(UNHANDLEDREJECTION, true, true); extend(event, eventData); } else if (_global.CustomEvent) { event = new CustomEvent(UNHANDLEDREJECTION, { detail: eventData }); extend(event, eventData); } if (event && _global.dispatchEvent) { dispatchEvent(event); if (!_global.PromiseRejectionEvent && _global.onunhandledrejection) try { _global.onunhandledrejection(event); } catch (_) { } } if (debug && event && !event.defaultPrevented) { console.warn(`Unhandled rejection: ${err.stack || err}`); } } catch (e) { } } var rejection = DexiePromise.reject; function tempTransaction(db2, mode, storeNames, fn) { if (!db2.idbdb || !db2._state.openComplete && (!PSD.letThrough && !db2._vip)) { if (db2._state.openComplete) { return rejection(new exceptions.DatabaseClosed(db2._state.dbOpenError)); } if (!db2._state.isBeingOpened) { if (!db2._options.autoOpen) return rejection(new exceptions.DatabaseClosed()); db2.open().catch(nop); } return db2._state.dbReadyPromise.then(() => tempTransaction(db2, mode, storeNames, fn)); } else { var trans = db2._createTransaction(mode, storeNames, db2._dbSchema); try { trans.create(); db2._state.PR1398_maxLoop = 3; } catch (ex) { if (ex.name === errnames.InvalidState && db2.isOpen() && --db2._state.PR1398_maxLoop > 0) { console.warn("Dexie: Need to reopen db"); db2._close(); return db2.open().then(() => tempTransaction(db2, mode, storeNames, fn)); } return rejection(ex); } return trans._promise(mode, (resolve, reject) => { return newScope(() => { PSD.trans = trans; return fn(resolve, reject, trans); }); }).then((result) => { return trans._completion.then(() => result); }); } } var DEXIE_VERSION = "3.2.7"; var maxString = String.fromCharCode(65535); var minKey = -Infinity; var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>."; var STRING_EXPECTED = "String expected."; var connections = []; var isIEOrEdge = typeof navigator !== "undefined" && /(MSIE|Trident|Edge)/.test(navigator.userAgent); var hasIEDeleteObjectStoreBug = isIEOrEdge; var hangsOnDeleteLargeKeyRange = isIEOrEdge; var dexieStackFrameFilter = (frame) => !/(dexie\.js|dexie\.min\.js)/.test(frame); var DBNAMES_DB = "__dbnames"; var READONLY = "readonly"; var READWRITE = "readwrite"; function combine(filter1, filter2) { return filter1 ? filter2 ? function() { return filter1.apply(this, arguments) && filter2.apply(this, arguments); } : filter1 : filter2; } var AnyRange = { type: 3, lower: -Infinity, lowerOpen: false, upper: [[]], upperOpen: false }; function workaroundForUndefinedPrimKey(keyPath) { return typeof keyPath === "string" && !/\./.test(keyPath) ? (obj) => { if (obj[keyPath] === void 0 && keyPath in obj) { obj = deepClone(obj); delete obj[keyPath]; } return obj; } : (obj) => obj; } var Table = class { _trans(mode, fn, writeLocked) { const trans = this._tx || PSD.trans; const tableName = this.name; function checkTableInTransaction(resolve, reject, trans2) { if (!trans2.schema[tableName]) throw new exceptions.NotFound("Table " + tableName + " not part of transaction"); return fn(trans2.idbtrans, trans2); } const wasRootExec = beginMicroTickScope(); try { return trans && trans.db === this.db ? trans === PSD.trans ? trans._promise(mode, checkTableInTransaction, writeLocked) : newScope(() => trans._promise(mode, checkTableInTransaction, writeLocked), { trans, transless: PSD.transless || PSD }) : tempTransaction(this.db, mode, [this.name], checkTableInTransaction); } finally { if (wasRootExec) endMicroTickScope(); } } get(keyOrCrit, cb) { if (keyOrCrit && keyOrCrit.constructor === Object) return this.where(keyOrCrit).first(cb); return this._trans("readonly", (trans) => { return this.core.get({ trans, key: keyOrCrit }).then((res) => this.hook.reading.fire(res)); }).then(cb); } where(indexOrCrit) { if (typeof indexOrCrit === "string") return new this.db.WhereClause(this, indexOrCrit); if (isArray2(indexOrCrit)) return new this.db.WhereClause(this, `[${indexOrCrit.join("+")}]`); const keyPaths = keys(indexOrCrit); if (keyPaths.length === 1) return this.where(keyPaths[0]).equals(indexOrCrit[keyPaths[0]]); const compoundIndex = this.schema.indexes.concat(this.schema.primKey).filter((ix) => { if (ix.compound && keyPaths.every((keyPath) => ix.keyPath.indexOf(keyPath) >= 0)) { for (let i = 0; i < keyPaths.length; ++i) { if (keyPaths.indexOf(ix.keyPath[i]) === -1) return false; } return true; } return false; }).sort((a, b) => a.keyPath.length - b.keyPath.length)[0]; if (compoundIndex && this.db._maxKey !== maxString) { const keyPathsInValidOrder = compoundIndex.keyPath.slice(0, keyPaths.length); return this.where(keyPathsInValidOrder).equals(keyPathsInValidOrder.map((kp) => indexOrCrit[kp])); } if (!compoundIndex && debug) console.warn(`The query ${JSON.stringify(indexOrCrit)} on ${this.name} would benefit of a compound index [${keyPaths.join("+")}]`); const { idxByName } = this.schema; const idb = this.db._deps.indexedDB; function equals(a, b) { try { return idb.cmp(a, b) === 0; } catch (e) { return false; } } const [idx, filterFunction] = keyPaths.reduce(([prevIndex, prevFilterFn], keyPath) => { const index = idxByName[keyPath]; const value = indexOrCrit[keyPath]; return [ prevIndex || index, prevIndex || !index ? combine(prevFilterFn, index && index.multi ? (x) => { const prop = getByKeyPath(x, keyPath); return isArray2(prop) && prop.some((item) => equals(value, item)); } : (x) => equals(value, getByKeyPath(x, keyPath))) : prevFilterFn ]; }, [null, null]); return idx ? this.where(idx.name).equals(indexOrCrit[idx.keyPath]).filter(filterFunction) : compoundIndex ? this.filter(filterFunction) : this.where(keyPaths).equals(""); } filter(filterFunction) { return this.toCollection().and(filterFunction); } count(thenShortcut) { return this.toCollection().count(thenShortcut); } offset(offset) { return this.toCollection().offset(offset); } limit(numRows) { return this.toCollection().limit(numRows); } each(callback) { return this.toCollection().each(callback); } toArray(thenShortcut) { return this.toCollection().toArray(thenShortcut); } toCollection() { return new this.db.Collection(new this.db.WhereClause(this)); } orderBy(index) { return new this.db.Collection(new this.db.WhereClause(this, isArray2(index) ? `[${index.join("+")}]` : index)); } reverse() { return this.toCollection().reverse(); } mapToClass(constructor) { this.schema.mappedClass = constructor; const readHook = (obj) => { if (!obj) return obj; const res = Object.create(constructor.prototype); for (var m in obj) if (hasOwn(obj, m)) try { res[m] = obj[m]; } catch (_) { } return res; }; if (this.schema.readHook) { this.hook.reading.unsubscribe(this.schema.readHook); } this.schema.readHook = readHook; this.hook("reading", readHook); return constructor; } defineClass() { function Class(content) { extend(this, content); } return this.mapToClass(Class); } add(obj, key) { const { auto, keyPath } = this.schema.primKey; let objToAdd = obj; if (keyPath && auto) { objToAdd = workaroundForUndefinedPrimKey(keyPath)(obj); } return this._trans("readwrite", (trans) => { return this.core.mutate({ trans, type: "add", keys: key != null ? [key] : null, values: [objToAdd] }); }).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult).then((lastResult) => { if (keyPath) { try { setByKeyPath(obj, keyPath, lastResult); } catch (_) { } } return lastResult; }); } update(keyOrObject, modifications) { if (typeof keyOrObject === "object" && !isArray2(keyOrObject)) { const key = getByKeyPath(keyOrObject, this.schema.primKey.keyPath); if (key === void 0) return rejection(new exceptions.InvalidArgument("Given object does not contain its primary key")); try { if (typeof modifications !== "function") { keys(modifications).forEach((keyPath) => { setByKeyPath(keyOrObject, keyPath, modifications[keyPath]); }); } else { modifications(keyOrObject, { value: keyOrObject, primKey: key }); } } catch (_a) { } return this.where(":id").equals(key).modify(modifications); } else { return this.where(":id").equals(keyOrObject).modify(modifications); } } put(obj, key) { const { auto, keyPath } = this.schema.primKey; let objToAdd = obj; if (keyPath && auto) { objToAdd = workaroundForUndefinedPrimKey(keyPath)(obj); } return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "put", values: [objToAdd], keys: key != null ? [key] : null })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult).then((lastResult) => { if (keyPath) { try { setByKeyPath(obj, keyPath, lastResult); } catch (_) { } } return lastResult; }); } delete(key) { return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "delete", keys: [key] })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : void 0); } clear() { return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "deleteRange", range: AnyRange })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : void 0); } bulkGet(keys2) { return this._trans("readonly", (trans) => { return this.core.getMany({ keys: keys2, trans }).then((result) => result.map((res) => this.hook.reading.fire(res))); }); } bulkAdd(objects, keysOrOptions, options) { const keys2 = Array.isArray(keysOrOptions) ? keysOrOptions : void 0; options = options || (keys2 ? void 0 : keysOrOptions); const wantResults = options ? options.allKeys : void 0; return this._trans("readwrite", (trans) => { const { auto, keyPath } = this.schema.primKey; if (keyPath && keys2) throw new exceptions.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys"); if (keys2 && keys2.length !== objects.length) throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length"); const numObjects = objects.length; let objectsToAdd = keyPath && auto ? objects.map(workaroundForUndefinedPrimKey(keyPath)) : objects; return this.core.mutate({ trans, type: "add", keys: keys2, values: objectsToAdd, wantResults }).then(({ numFailures, results, lastResult, failures }) => { const result = wantResults ? results : lastResult; if (numFailures === 0) return result; throw new BulkError(`${this.name}.bulkAdd(): ${numFailures} of ${numObjects} operations failed`, failures); }); }); } bulkPut(objects, keysOrOptions, options) { const keys2 = Array.isArray(keysOrOptions) ? keysOrOptions : void 0; options = options || (keys2 ? void 0 : keysOrOptions); const wantResults = options ? options.allKeys : void 0; return this._trans("readwrite", (trans) => { const { auto, keyPath } = this.schema.primKey; if (keyPath && keys2) throw new exceptions.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys"); if (keys2 && keys2.length !== objects.length) throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length"); const numObjects = objects.length; let objectsToPut = keyPath && auto ? objects.map(workaroundForUndefinedPrimKey(keyPath)) : objects; return this.core.mutate({ trans, type: "put", keys: keys2, values: objectsToPut, wantResults }).then(({ numFailures, results, lastResult, failures }) => { const result = wantResults ? results : lastResult; if (numFailures === 0) return result; throw new BulkError(`${this.name}.bulkPut(): ${numFailures} of ${numObjects} operations failed`, failures); }); }); } bulkDelete(keys2) { const numKeys = keys2.length; return this._trans("readwrite", (trans) => { return this.core.mutate({ trans, type: "delete", keys: keys2 }); }).then(({ numFailures, lastResult, failures }) => { if (numFailures === 0) return lastResult; throw new BulkError(`${this.name}.bulkDelete(): ${numFailures} of ${numKeys} operations failed`, failures); }); } }; function Events(ctx) { var evs = {}; var rv = function(eventName, subscriber) { if (subscriber) { var i2 = arguments.length, args = new Array(i2 - 1); while (--i2) args[i2 - 1] = arguments[i2]; evs[eventName].subscribe.apply(null, args); return ctx; } else if (typeof eventName === "string") { return evs[eventName]; } }; rv.addEventType = add; for (var i = 1, l = arguments.length; i < l; ++i) { add(arguments[i]); } return rv; function add(eventName, chainFunction, defaultFunction) { if (typeof eventName === "object") return addConfiguredEvents(eventName); if (!chainFunction) chainFunction = reverseStoppableEventChain; if (!defaultFunction) defaultFunction = nop; var context = { subscribers: [], fire: defaultFunction, subscribe: function(cb) { if (context.subscribers.indexOf(cb) === -1) { context.subscribers.push(cb); context.fire = chainFunction(context.fire, cb); } }, unsubscribe: function(cb) { context.subscribers = context.subscribers.filter(function(fn) { return fn !== cb; }); context.fire = context.subscribers.reduce(chainFunction, defaultFunction); } }; evs[eventName] = rv[eventName] = context; return context; } function addConfiguredEvents(cfg) { keys(cfg).forEach(function(eventName) { var args = cfg[eventName]; if (isArray2(args)) { add(eventName, cfg[eventName][0], cfg[eventName][1]); } else if (args === "asap") { var context = add(eventName, mirror, function fire() { var i2 = arguments.length, args2 = new Array(i2); while (i2--) args2[i2] = arguments[i2]; context.subscribers.forEach(function(fn) { asap$1(function fireEvent() { fn.apply(null, args2); }); }); }); } else throw new exceptions.InvalidArgument("Invalid event config"); }); } } function makeClassConstructor(prototype, constructor) { derive(constructor).from({ prototype }); return constructor; } function createTableConstructor(db2) { return makeClassConstructor(Table.prototype, function Table2(name, tableSchema, trans) { this.db = db2; this._tx = trans; this.name = name; this.schema = tableSchema; this.hook = db2._allTables[name] ? db2._allTables[name].hook : Events(null, { "creating": [hookCreatingChain, nop], "reading": [pureFunctionChain, mirror], "updating": [hookUpdatingChain, nop], "deleting": [hookDeletingChain, nop] }); }); } function isPlainKeyRange(ctx, ignoreLimitFilter) { return !(ctx.filter || ctx.algorithm || ctx.or) && (ignoreLimitFilter ? ctx.justLimit : !ctx.replayFilter); } function addFilter(ctx, fn) { ctx.filter = combine(ctx.filter, fn); } function addReplayFilter(ctx, factory, isLimitFilter) { var curr = ctx.replayFilter; ctx.replayFilter = curr ? () => combine(curr(), factory()) : factory; ctx.justLimit = isLimitFilter && !curr; } function addMatchFilter(ctx, fn) { ctx.isMatch = combine(ctx.isMatch, fn); } function getIndexOrStore(ctx, coreSchema) { if (ctx.isPrimKey) return coreSchema.primaryKey; const index = coreSchema.getIndexByKeyPath(ctx.index); if (!index) throw new exceptions.Schema("KeyPath " + ctx.index + " on object store " + coreSchema.name + " is not indexed"); return index; } function openCursor(ctx, coreTable, trans) { const index = getIndexOrStore(ctx, coreTable.schema); return coreTable.openCursor({ trans, values: !ctx.keysOnly, reverse: ctx.dir === "prev", unique: !!ctx.unique, query: { index, range: ctx.range } }); } function iter(ctx, fn, coreTrans, coreTable) { const filter = ctx.replayFilter ? combine(ctx.filter, ctx.replayFilter()) : ctx.filter; if (!ctx.or) { return iterate(openCursor(ctx, coreTable, coreTrans), combine(ctx.algorithm, filter), fn, !ctx.keysOnly && ctx.valueMapper); } else { const set = {}; const union = (item, cursor, advance) => { if (!filter || filter(cursor, advance, (result) => cursor.stop(result), (err) => cursor.fail(err))) { var primaryKey = cursor.primaryKey; var key = "" + primaryKey; if (key === "[object ArrayBuffer]") key = "" + new Uint8Array(primaryKey); if (!hasOwn(set, key)) { set[key] = true; fn(item, cursor, advance); } } }; return Promise.all([ ctx.or._iterate(union, coreTrans), iterate(openCursor(ctx, coreTable, coreTrans), ctx.algorithm, union, !ctx.keysOnly && ctx.valueMapper) ]); } } function iterate(cursorPromise, filter, fn, valueMapper) { var mappedFn = valueMapper ? (x, c, a) => fn(valueMapper(x), c, a) : fn; var wrappedFn = wrap(mappedFn); return cursorPromise.then((cursor) => { if (cursor) { return cursor.start(() => { var c = () => cursor.continue(); if (!filter || filter(cursor, (advancer) => c = advancer, (val) => { cursor.stop(val); c = nop; }, (e) => { cursor.fail(e); c = nop; })) wrappedFn(cursor.value, cursor, (advancer) => c = advancer); c(); }); } }); } function cmp(a, b) { try { const ta = type(a); const tb = type(b); if (ta !== tb) { if (ta === "Array") return 1; if (tb === "Array") return -1; if (ta === "binary") return 1; if (tb === "binary") return -1; if (ta === "string") return 1; if (tb === "string") return -1; if (ta === "Date") return 1; if (tb !== "Date") return NaN; return -1; } switch (ta) { case "number": case "Date": case "string": return a > b ? 1 : a < b ? -1 : 0; case "binary": { return compareUint8Arrays(getUint8Array(a), getUint8Array(b)); } case "Array": return compareArrays(a, b); } } catch (_a) { } return NaN; } function compareArrays(a, b) { const al = a.length; const bl = b.length; const l = al < bl ? al : bl; for (let i = 0; i < l; ++i) { const res = cmp(a[i], b[i]); if (res !== 0) return res; } return al === bl ? 0 : al < bl ? -1 : 1; } function compareUint8Arrays(a, b) { const al = a.length; const bl = b.length; const l = al < bl ? al : bl; for (let i = 0; i < l; ++i) { if (a[i] !== b[i]) return a[i] < b[i] ? -1 : 1; } return al === bl ? 0 : al < bl ? -1 : 1; } function type(x) { const t = typeof x; if (t !== "object") return t; if (ArrayBuffer.isView(x)) return "binary"; const tsTag = toStringTag(x); return tsTag === "ArrayBuffer" ? "binary" : tsTag; } function getUint8Array(a) { if (a instanceof Uint8Array) return a; if (ArrayBuffer.isView(a)) return new Uint8Array(a.buffer, a.byteOffset, a.byteLength); return new Uint8Array(a); } var Collection = class { _read(fn, cb) { var ctx = this._ctx; return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans("readonly", fn).then(cb); } _write(fn) { var ctx = this._ctx; return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans("readwrite", fn, "locked"); } _addAlgorithm(fn) { var ctx = this._ctx; ctx.algorithm = combine(ctx.algorithm, fn); } _iterate(fn, coreTrans) { return iter(this._ctx, fn, coreTrans, this._ctx.table.core); } clone(props2) { var rv = Object.create(this.constructor.prototype), ctx = Object.create(this._ctx); if (props2) extend(ctx, props2); rv._ctx = ctx; return rv; } raw() { this._ctx.valueMapper = null; return this; } each(fn) { var ctx = this._ctx; return this._read((trans) => iter(ctx, fn, trans, ctx.table.core)); } count(cb) { return this._read((trans) => { const ctx = this._ctx; const coreTable = ctx.table.core; if (isPlainKeyRange(ctx, true)) { return coreTable.count({ trans, query: { index: getIndexOrStore(ctx, coreTable.schema), range: ctx.range } }).then((count2) => Math.min(count2, ctx.limit)); } else { var count = 0; return iter(ctx, () => { ++count; return false; }, trans, coreTable).then(() => count); } }).then(cb); } sortBy(keyPath, cb) { const parts = keyPath.split(".").reverse(), lastPart = parts[0], lastIndex = parts.length - 1; function getval(obj, i) { if (i) return getval(obj[parts[i]], i - 1); return obj[lastPart]; } var order = this._ctx.dir === "next" ? 1 : -1; function sorter(a, b) { var aVal = getval(a, lastIndex), bVal = getval(b, lastIndex); return aVal < bVal ? -order : aVal > bVal ? order : 0; } return this.toArray(function(a) { return a.sort(sorter); }).then(cb); } toArray(cb) { return this._read((trans) => { var ctx = this._ctx; if (ctx.dir === "next" && isPlainKeyRange(ctx, true) && ctx.limit > 0) { const { valueMapper } = ctx; const index = getIndexOrStore(ctx, ctx.table.core.schema); return ctx.table.core.query({ trans, limit: ctx.limit, values: true, query: { index, range: ctx.range } }).then(({ result }) => valueMapper ? result.map(valueMapper) : result); } else { const a = []; return iter(ctx, (item) => a.push(item), trans, ctx.table.core).then(() => a); } }, cb); } offset(offset) { var ctx = this._ctx; if (offset <= 0) return this; ctx.offset += offset; if (isPlainKeyRange(ctx)) { addReplayFilter(ctx, () => { var offsetLeft = offset; return (cursor, advance) => { if (offsetLeft === 0) return true; if (offsetLeft === 1) { --offsetLeft; return false; } advance(() => { cursor.advance(offsetLeft); offsetLeft = 0; }); return false; }; }); } else { addReplayFilter(ctx, () => { var offsetLeft = offset; return () => --offsetLeft < 0; }); } return this; } limit(numRows) { this._ctx.limit = Math.min(this._ctx.limit, numRows); addReplayFilter(this._ctx, () => { var rowsLeft = numRows; return function(cursor, advance, resolve) { if (--rowsLeft <= 0) advance(resolve); return rowsLeft >= 0; }; }, true); return this; } until(filterFunction, bIncludeStopEntry) { addFilter(this._ctx, function(cursor, advance, resolve) { if (filterFunction(cursor.value)) { advance(resolve); return bIncludeStopEntry; } else { return true; } }); return this; } first(cb) { return this.limit(1).toArray(function(a) { return a[0]; }).then(cb); } last(cb) { return this.reverse().first(cb); } filter(filterFunction) { addFilter(this._ctx, function(cursor) { return filterFunction(cursor.value); }); addMatchFilter(this._ctx, filterFunction); return this; } and(filter) { return this.filter(filter); } or(indexName) { return new this.db.WhereClause(this._ctx.table, indexName, this); } reverse() { this._ctx.dir = this._ctx.dir === "prev" ? "next" : "prev"; if (this._ondirectionchange) this._ondirectionchange(this._ctx.dir); return this; } desc() { return this.reverse(); } eachKey(cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; return this.each(function(val, cursor) { cb(cursor.key, cursor); }); } eachUniqueKey(cb) { this._ctx.unique = "unique"; return this.eachKey(cb); } eachPrimaryKey(cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; return this.each(function(val, cursor) { cb(cursor.primaryKey, cursor); }); } keys(cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; var a = []; return this.each(function(item, cursor) { a.push(cursor.key); }).then(function() { return a; }).then(cb); } primaryKeys(cb) { var ctx = this._ctx; if (ctx.dir === "next" && isPlainKeyRange(ctx, true) && ctx.limit > 0) { return this._read((trans) => { var index = getIndexOrStore(ctx, ctx.table.core.schema); return ctx.table.core.query({ trans, values: false, limit: ctx.limit, query: { index, range: ctx.range } }); }).then(({ result }) => result).then(cb); } ctx.keysOnly = !ctx.isMatch; var a = []; return this.each(function(item, cursor) { a.push(cursor.primaryKey); }).then(function() { return a; }).then(cb); } uniqueKeys(cb) { this._ctx.unique = "unique"; return this.keys(cb); } firstKey(cb) { return this.limit(1).keys(function(a) { return a[0]; }).then(cb); } lastKey(cb) { return this.reverse().firstKey(cb); } distinct() { var ctx = this._ctx, idx = ctx.index && ctx.table.schema.idxByName[ctx.index]; if (!idx || !idx.multi) return this; var set = {}; addFilter(this._ctx, function(cursor) { var strKey = cursor.primaryKey.toString(); var found = hasOwn(set, strKey); set[strKey] = true; return !found; }); return this; } modify(changes) { var ctx = this._ctx; return this._write((trans) => { var modifyer; if (typeof changes === "function") { modifyer = changes; } else { var keyPaths = keys(changes); var numKeys = keyPaths.length; modifyer = function(item) { var anythingModified = false; for (var i = 0; i < numKeys; ++i) { var keyPath = keyPaths[i], val = changes[keyPath]; if (getByKeyPath(item, keyPath) !== val) { setByKeyPath(item, keyPath, val); anythingModified = true; } } return anythingModified; }; } const coreTable = ctx.table.core; const { outbound, extractKey } = coreTable.schema.primaryKey; const limit = this.db._options.modifyChunkSize || 200; const totalFailures = []; let successCount = 0; const failedKeys = []; const applyMutateResult = (expectedCount, res) => { const { failures, numFailures } = res; successCount += expectedCount - numFailures; for (let pos of keys(failures)) { totalFailures.push(failures[pos]); } }; return this.clone().primaryKeys().then((keys2) => { const nextChunk = (offset) => { const count = Math.min(limit, keys2.length - offset); return coreTable.getMany({ trans, keys: keys2.slice(offset, offset + count), cache: "immutable" }).then((values) => { const addValues = []; const putValues = []; const putKeys = outbound ? [] : null; const deleteKeys = []; for (let i = 0; i < count; ++i) { const origValue = values[i]; const ctx2 = { value: deepClone(origValue), primKey: keys2[offset + i] }; if (modifyer.call(ctx2, ctx2.value, ctx2) !== false) { if (ctx2.value == null) { deleteKeys.push(keys2[offset + i]); } else if (!outbound && cmp(extractKey(origValue), extractKey(ctx2.value)) !== 0) { deleteKeys.push(keys2[offset + i]); addValues.push(ctx2.value); } else { putValues.push(ctx2.value); if (outbound) putKeys.push(keys2[offset + i]); } } } const criteria = isPlainKeyRange(ctx) && ctx.limit === Infinity && (typeof changes !== "function" || changes === deleteCallback) && { index: ctx.index, range: ctx.range }; return Promise.resolve(addValues.length > 0 && coreTable.mutate({ trans, type: "add", values: addValues }).then((res) => { for (let pos in res.failures) { deleteKeys.splice(parseInt(pos), 1); } applyMutateResult(addValues.length, res); })).then(() => (putValues.length > 0 || criteria && typeof changes === "object") && coreTable.mutate({ trans, type: "put", keys: putKeys, values: putValues, criteria, changeSpec: typeof changes !== "function" && changes }).then((res) => applyMutateResult(putValues.length, res))).then(() => (deleteKeys.length > 0 || criteria && changes === deleteCallback) && coreTable.mutate({ trans, type: "delete", keys: deleteKeys, criteria }).then((res) => applyMutateResult(deleteKeys.length, res))).then(() => { return keys2.length > offset + count && nextChunk(offset + limit); }); }); }; return nextChunk(0).then(() => { if (totalFailures.length > 0) throw new ModifyError("Error modifying one or more objects", totalFailures, successCount, failedKeys); return keys2.length; }); }); }); } delete() { var ctx = this._ctx, range = ctx.range; if (isPlainKeyRange(ctx) && (ctx.isPrimKey && !hangsOnDeleteLargeKeyRange || range.type === 3)) { return this._write((trans) => { const { primaryKey } = ctx.table.core.schema; const coreRange = range; return ctx.table.core.count({ trans, query: { index: primaryKey, range: coreRange } }).then((count) => { return ctx.table.core.mutate({ trans, type: "deleteRange", range: coreRange }).then(({ failures, lastResult, results, numFailures }) => { if (numFailures) throw new ModifyError("Could not delete some values", Object.keys(failures).map((pos) => failures[pos]), count - numFailures); return count - numFailures; }); }); }); } return this.modify(deleteCallback); } }; var deleteCallback = (value, ctx) => ctx.value = null; function createCollectionConstructor(db2) { return makeClassConstructor(Collection.prototype, function Collection2(whereClause, keyRangeGenerator) { this.db = db2; let keyRange = AnyRange, error = null; if (keyRangeGenerator) try { keyRange = keyRangeGenerator(); } catch (ex) { error = ex; } const whereCtx = whereClause._ctx; const table = whereCtx.table; const readingHook = table.hook.reading.fire; this._ctx = { table, index: whereCtx.index, isPrimKey: !whereCtx.index || table.schema.primKey.keyPath && whereCtx.index === table.schema.primKey.name, range: keyRange, keysOnly: false, dir: "next", unique: "", algorithm: null, filter: null, replayFilter: null, justLimit: true, isMatch: null, offset: 0, limit: Infinity, error, or: whereCtx.or, valueMapper: readingHook !== mirror ? readingHook : null }; }); } function simpleCompare(a, b) { return a < b ? -1 : a === b ? 0 : 1; } function simpleCompareReverse(a, b) { return a > b ? -1 : a === b ? 0 : 1; } function fail(collectionOrWhereClause, err, T) { var collection = collectionOrWhereClause instanceof WhereClause ? new collectionOrWhereClause.Collection(collectionOrWhereClause) : collectionOrWhereClause; collection._ctx.error = T ? new T(err) : new TypeError(err); return collection; } function emptyCollection(whereClause) { return new whereClause.Collection(whereClause, () => rangeEqual("")).limit(0); } function upperFactory(dir) { return dir === "next" ? (s) => s.toUpperCase() : (s) => s.toLowerCase(); } function lowerFactory(dir) { return dir === "next" ? (s) => s.toLowerCase() : (s) => s.toUpperCase(); } function nextCasing(key, lowerKey, upperNeedle, lowerNeedle, cmp2, dir) { var length = Math.min(key.length, lowerNeedle.length); var llp = -1; for (var i = 0; i < length; ++i) { var lwrKeyChar = lowerKey[i]; if (lwrKeyChar !== lowerNeedle[i]) { if (cmp2(key[i], upperNeedle[i]) < 0) return key.substr(0, i) + upperNeedle[i] + upperNeedle.substr(i + 1); if (cmp2(key[i], lowerNeedle[i]) < 0) return key.substr(0, i) + lowerNeedle[i] + upperNeedle.substr(i + 1); if (llp >= 0) return key.substr(0, llp) + lowerKey[llp] + upperNeedle.substr(llp + 1); return null; } if (cmp2(key[i], lwrKeyChar) < 0) llp = i; } if (length < lowerNeedle.length && dir === "next") return key + upperNeedle.substr(key.length); if (length < key.length && dir === "prev") return key.substr(0, upperNeedle.length); return llp < 0 ? null : key.substr(0, llp) + lowerNeedle[llp] + upperNeedle.substr(llp + 1); } function addIgnoreCaseAlgorithm(whereClause, match, needles, suffix) { var upper, lower, compare, upperNeedles, lowerNeedles, direction, nextKeySuffix, needlesLen = needles.length; if (!needles.every((s) => typeof s === "string")) { return fail(whereClause, STRING_EXPECTED); } function initDirection(dir) { upper = upperFactory(dir); lower = lowerFactory(dir); compare = dir === "next" ? simpleCompare : simpleCompareReverse; var needleBounds = needles.map(function(needle) { return { lower: lower(needle), upper: upper(needle) }; }).sort(function(a, b) { return compare(a.lower, b.lower); }); upperNeedles = needleBounds.map(function(nb) { return nb.upper; }); lowerNeedles = needleBounds.map(function(nb) { return nb.lower; }); direction = dir; nextKeySuffix = dir === "next" ? "" : suffix; } initDirection("next"); var c = new whereClause.Collection(whereClause, () => createRange(upperNeedles[0], lowerNeedles[needlesLen - 1] + suffix)); c._ondirectionchange = function(direction2) { initDirection(direction2); }; var firstPossibleNeedle = 0; c._addAlgorithm(function(cursor, advance, resolve) { var key = cursor.key; if (typeof key !== "string") return false; var lowerKey = lower(key); if (match(lowerKey, lowerNeedles, firstPossibleNeedle)) { return true; } else { var lowestPossibleCasing = null; for (var i = firstPossibleNeedle; i < needlesLen; ++i) { var casing = nextCasing(key, lowerKey, upperNeedles[i], lowerNeedles[i], compare, direction); if (casing === null && lowestPossibleCasing === null) firstPossibleNeedle = i + 1; else if (lowestPossibleCasing === null || compare(lowestPossibleCasing, casing) > 0) { lowestPossibleCasing = casing; } } if (lowestPossibleCasing !== null) { advance(function() { cursor.continue(lowestPossibleCasing + nextKeySuffix); }); } else { advance(resolve); } return false; } }); return c; } function createRange(lower, upper, lowerOpen, upperOpen) { return { type: 2, lower, upper, lowerOpen, upperOpen }; } function rangeEqual(value) { return { type: 1, lower: value, upper: value }; } var WhereClause = class { get Collection() { return this._ctx.table.db.Collection; } between(lower, upper, includeLower, includeUpper) { includeLower = includeLower !== false; includeUpper = includeUpper === true; try { if (this._cmp(lower, upper) > 0 || this._cmp(lower, upper) === 0 && (includeLower || includeUpper) && !(includeLower && includeUpper)) return emptyCollection(this); return new this.Collection(this, () => createRange(lower, upper, !includeLower, !includeUpper)); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } } equals(value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, () => rangeEqual(value)); } above(value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, () => createRange(value, void 0, true)); } aboveOrEqual(value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, () => createRange(value, void 0, false)); } below(value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, () => createRange(void 0, value, false, true)); } belowOrEqual(value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, () => createRange(void 0, value)); } startsWith(str) { if (typeof str !== "string") return fail(this, STRING_EXPECTED); return this.between(str, str + maxString, true, true); } startsWithIgnoreCase(str) { if (str === "") return this.startsWith(str); return addIgnoreCaseAlgorithm(this, (x, a) => x.indexOf(a[0]) === 0, [str], maxString); } equalsIgnoreCase(str) { return addIgnoreCaseAlgorithm(this, (x, a) => x === a[0], [str], ""); } anyOfIgnoreCase() { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return emptyCollection(this); return addIgnoreCaseAlgorithm(this, (x, a) => a.indexOf(x) !== -1, set, ""); } startsWithAnyOfIgnoreCase() { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return emptyCollection(this); return addIgnoreCaseAlgorithm(this, (x, a) => a.some((n) => x.indexOf(n) === 0), set, maxString); } anyOf() { const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); let compare = this._cmp; try { set.sort(compare); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } if (set.length === 0) return emptyCollection(this); const c = new this.Collection(this, () => createRange(set[0], set[set.length - 1])); c._ondirectionchange = (direction) => { compare = direction === "next" ? this._ascending : this._descending; set.sort(compare); }; let i = 0; c._addAlgorithm((cursor, advance, resolve) => { const key = cursor.key; while (compare(key, set[i]) > 0) { ++i; if (i === set.length) { advance(resolve); return false; } } if (compare(key, set[i]) === 0) { return true; } else { advance(() => { cursor.continue(set[i]); }); return false; } }); return c; } notEqual(value) { return this.inAnyRange([[minKey, value], [value, this.db._maxKey]], { includeLowers: false, includeUppers: false }); } noneOf() { const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return new this.Collection(this); try { set.sort(this._ascending); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } const ranges = set.reduce((res, val) => res ? res.concat([[res[res.length - 1][1], val]]) : [[minKey, val]], null); ranges.push([set[set.length - 1], this.db._maxKey]); return this.inAnyRange(ranges, { includeLowers: false, includeUppers: false }); } inAnyRange(ranges, options) { const cmp2 = this._cmp, ascending = this._ascending, descending = this._descending, min = this._min, max = this._max; if (ranges.length === 0) return emptyCollection(this); if (!ranges.every((range) => range[0] !== void 0 && range[1] !== void 0 && ascending(range[0], range[1]) <= 0)) { return fail(this, "First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower", exceptions.InvalidArgument); } const includeLowers = !options || options.includeLowers !== false; const includeUppers = options && options.includeUppers === true; function addRange2(ranges2, newRange) { let i = 0, l = ranges2.length; for (; i < l; ++i) { const range = ranges2[i]; if (cmp2(newRange[0], range[1]) < 0 && cmp2(newRange[1], range[0]) > 0) { range[0] = min(range[0], newRange[0]); range[1] = max(range[1], newRange[1]); break; } } if (i === l) ranges2.push(newRange); return ranges2; } let sortDirection = ascending; function rangeSorter(a, b) { return sortDirection(a[0], b[0]); } let set; try { set = ranges.reduce(addRange2, []); set.sort(rangeSorter); } catch (ex) { return fail(this, INVALID_KEY_ARGUMENT); } let rangePos = 0; const keyIsBeyondCurrentEntry = includeUppers ? (key) => ascending(key, set[rangePos][1]) > 0 : (key) => ascending(key, set[rangePos][1]) >= 0; const keyIsBeforeCurrentEntry = includeLowers ? (key) => descending(key, set[rangePos][0]) > 0 : (key) => descending(key, set[rangePos][0]) >= 0; function keyWithinCurrentRange(key) { return !keyIsBeyondCurrentEntry(key) && !keyIsBeforeCurrentEntry(key); } let checkKey = keyIsBeyondCurrentEntry; const c = new this.Collection(this, () => createRange(set[0][0], set[set.length - 1][1], !includeLowers, !includeUppers)); c._ondirectionchange = (direction) => { if (direction === "next") { checkKey = keyIsBeyondCurrentEntry; sortDirection = ascending; } else { checkKey = keyIsBeforeCurrentEntry; sortDirection = descending; } set.sort(rangeSorter); }; c._addAlgorithm((cursor, advance, resolve) => { var key = cursor.key; while (checkKey(key)) { ++rangePos; if (rangePos === set.length) { advance(resolve); return false; } } if (keyWithinCurrentRange(key)) { return true; } else if (this._cmp(key, set[rangePos][1]) === 0 || this._cmp(key, set[rangePos][0]) === 0) { return false; } else { advance(() => { if (sortDirection === ascending) cursor.continue(set[rangePos][0]); else cursor.continue(set[rangePos][1]); }); return false; } }); return c; } startsWithAnyOf() { const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (!set.every((s) => typeof s === "string")) { return fail(this, "startsWithAnyOf() only works with strings"); } if (set.length === 0) return emptyCollection(this); return this.inAnyRange(set.map((str) => [str, str + maxString])); } }; function createWhereClauseConstructor(db2) { return makeClassConstructor(WhereClause.prototype, function WhereClause2(table, index, orCollection) { this.db = db2; this._ctx = { table, index: index === ":id" ? null : index, or: orCollection }; const indexedDB2 = db2._deps.indexedDB; if (!indexedDB2) throw new exceptions.MissingAPI(); this._cmp = this._ascending = indexedDB2.cmp.bind(indexedDB2); this._descending = (a, b) => indexedDB2.cmp(b, a); this._max = (a, b) => indexedDB2.cmp(a, b) > 0 ? a : b; this._min = (a, b) => indexedDB2.cmp(a, b) < 0 ? a : b; this._IDBKeyRange = db2._deps.IDBKeyRange; }); } function eventRejectHandler(reject) { return wrap(function(event) { preventDefault(event); reject(event.target.error); return false; }); } function preventDefault(event) { if (event.stopPropagation) event.stopPropagation(); if (event.preventDefault) event.preventDefault(); } var DEXIE_STORAGE_MUTATED_EVENT_NAME = "storagemutated"; var STORAGE_MUTATED_DOM_EVENT_NAME = "x-storagemutated-1"; var globalEvents = Events(null, DEXIE_STORAGE_MUTATED_EVENT_NAME); var Transaction = class { _lock() { assert(!PSD.global); ++this._reculock; if (this._reculock === 1 && !PSD.global) PSD.lockOwnerFor = this; return this; } _unlock() { assert(!PSD.global); if (--this._reculock === 0) { if (!PSD.global) PSD.lockOwnerFor = null; while (this._blockedFuncs.length > 0 && !this._locked()) { var fnAndPSD = this._blockedFuncs.shift(); try { usePSD(fnAndPSD[1], fnAndPSD[0]); } catch (e) { } } } return this; } _locked() { return this._reculock && PSD.lockOwnerFor !== this; } create(idbtrans) { if (!this.mode) return this; const idbdb = this.db.idbdb; const dbOpenError = this.db._state.dbOpenError; assert(!this.idbtrans); if (!idbtrans && !idbdb) { switch (dbOpenError && dbOpenError.name) { case "DatabaseClosedError": throw new exceptions.DatabaseClosed(dbOpenError); case "MissingAPIError": throw new exceptions.MissingAPI(dbOpenError.message, dbOpenError); default: throw new exceptions.OpenFailed(dbOpenError); } } if (!this.active) throw new exceptions.TransactionInactive(); assert(this._completion._state === null); idbtrans = this.idbtrans = idbtrans || (this.db.core ? this.db.core.transaction(this.storeNames, this.mode, { durability: this.chromeTransactionDurability }) : idbdb.transaction(this.storeNames, this.mode, { durability: this.chromeTransactionDurability })); idbtrans.onerror = wrap((ev) => { preventDefault(ev); this._reject(idbtrans.error); }); idbtrans.onabort = wrap((ev) => { preventDefault(ev); this.active && this._reject(new exceptions.Abort(idbtrans.error)); this.active = false; this.on("abort").fire(ev); }); idbtrans.oncomplete = wrap(() => { this.active = false; this._resolve(); if ("mutatedParts" in idbtrans) { globalEvents.storagemutated.fire(idbtrans["mutatedParts"]); } }); return this; } _promise(mode, fn, bWriteLock) { if (mode === "readwrite" && this.mode !== "readwrite") return rejection(new exceptions.ReadOnly("Transaction is readonly")); if (!this.active) return rejection(new exceptions.TransactionInactive()); if (this._locked()) { return new DexiePromise((resolve, reject) => { this._blockedFuncs.push([() => { this._promise(mode, fn, bWriteLock).then(resolve, reject); }, PSD]); }); } else if (bWriteLock) { return newScope(() => { var p2 = new DexiePromise((resolve, reject) => { this._lock(); const rv = fn(resolve, reject, this); if (rv && rv.then) rv.then(resolve, reject); }); p2.finally(() => this._unlock()); p2._lib = true; return p2; }); } else { var p = new DexiePromise((resolve, reject) => { var rv = fn(resolve, reject, this); if (rv && rv.then) rv.then(resolve, reject); }); p._lib = true; return p; } } _root() { return this.parent ? this.parent._root() : this; } waitFor(promiseLike) { var root = this._root(); const promise = DexiePromise.resolve(promiseLike); if (root._waitingFor) { root._waitingFor = root._waitingFor.then(() => promise); } else { root._waitingFor = promise; root._waitingQueue = []; var store = root.idbtrans.objectStore(root.storeNames[0]); (function spin() { ++root._spinCount; while (root._waitingQueue.length) root._waitingQueue.shift()(); if (root._waitingFor) store.get(-Infinity).onsuccess = spin; })(); } var currentWaitPromise = root._waitingFor; return new DexiePromise((resolve, reject) => { promise.then((res) => root._waitingQueue.push(wrap(resolve.bind(null, res))), (err) => root._waitingQueue.push(wrap(reject.bind(null, err)))).finally(() => { if (root._waitingFor === currentWaitPromise) { root._waitingFor = null; } }); }); } abort() { if (this.active) { this.active = false; if (this.idbtrans) this.idbtrans.abort(); this._reject(new exceptions.Abort()); } } table(tableName) { const memoizedTables = this._memoizedTables || (this._memoizedTables = {}); if (hasOwn(memoizedTables, tableName)) return memoizedTables[tableName]; const tableSchema = this.schema[tableName]; if (!tableSchema) { throw new exceptions.NotFound("Table " + tableName + " not part of transaction"); } const transactionBoundTable = new this.db.Table(tableName, tableSchema, this); transactionBoundTable.core = this.db.core.table(tableName); memoizedTables[tableName] = transactionBoundTable; return transactionBoundTable; } }; function createTransactionConstructor(db2) { return makeClassConstructor(Transaction.prototype, function Transaction2(mode, storeNames, dbschema, chromeTransactionDurability, parent) { this.db = db2; this.mode = mode; this.storeNames = storeNames; this.schema = dbschema; this.chromeTransactionDurability = chromeTransactionDurability; this.idbtrans = null; this.on = Events(this, "complete", "error", "abort"); this.parent = parent || null; this.active = true; this._reculock = 0; this._blockedFuncs = []; this._resolve = null; this._reject = null; this._waitingFor = null; this._waitingQueue = null; this._spinCount = 0; this._completion = new DexiePromise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); this._completion.then(() => { this.active = false; this.on.complete.fire(); }, (e) => { var wasActive = this.active; this.active = false; this.on.error.fire(e); this.parent ? this.parent._reject(e) : wasActive && this.idbtrans && this.idbtrans.abort(); return rejection(e); }); }); } function createIndexSpec(name, keyPath, unique, multi, auto, compound, isPrimKey) { return { name, keyPath, unique, multi, auto, compound, src: (unique && !isPrimKey ? "&" : "") + (multi ? "*" : "") + (auto ? "++" : "") + nameFromKeyPath(keyPath) }; } function nameFromKeyPath(keyPath) { return typeof keyPath === "string" ? keyPath : keyPath ? "[" + [].join.call(keyPath, "+") + "]" : ""; } function createTableSchema(name, primKey, indexes) { return { name, primKey, indexes, mappedClass: null, idxByName: arrayToObject(indexes, (index) => [index.name, index]) }; } function safariMultiStoreFix(storeNames) { return storeNames.length === 1 ? storeNames[0] : storeNames; } var getMaxKey = (IdbKeyRange) => { try { IdbKeyRange.only([[]]); getMaxKey = () => [[]]; return [[]]; } catch (e) { getMaxKey = () => maxString; return maxString; } }; function getKeyExtractor(keyPath) { if (keyPath == null) { return () => void 0; } else if (typeof keyPath === "string") { return getSinglePathKeyExtractor(keyPath); } else { return (obj) => getByKeyPath(obj, keyPath); } } function getSinglePathKeyExtractor(keyPath) { const split = keyPath.split("."); if (split.length === 1) { return (obj) => obj[keyPath]; } else { return (obj) => getByKeyPath(obj, keyPath); } } function arrayify(arrayLike) { return [].slice.call(arrayLike); } var _id_counter = 0; function getKeyPathAlias(keyPath) { return keyPath == null ? ":id" : typeof keyPath === "string" ? keyPath : `[${keyPath.join("+")}]`; } function createDBCore(db2, IdbKeyRange, tmpTrans) { function extractSchema(db3, trans) { const tables2 = arrayify(db3.objectStoreNames); return { schema: { name: db3.name, tables: tables2.map((table) => trans.objectStore(table)).map((store) => { const { keyPath, autoIncrement } = store; const compound = isArray2(keyPath); const outbound = keyPath == null; const indexByKeyPath = {}; const result = { name: store.name, primaryKey: { name: null, isPrimaryKey: true, outbound, compound, keyPath, autoIncrement, unique: true, extractKey: getKeyExtractor(keyPath) }, indexes: arrayify(store.indexNames).map((indexName) => store.index(indexName)).map((index) => { const { name, unique, multiEntry, keyPath: keyPath2 } = index; const compound2 = isArray2(keyPath2); const result2 = { name, compound: compound2, keyPath: keyPath2, unique, multiEntry, extractKey: getKeyExtractor(keyPath2) }; indexByKeyPath[getKeyPathAlias(keyPath2)] = result2; return result2; }), getIndexByKeyPath: (keyPath2) => indexByKeyPath[getKeyPathAlias(keyPath2)] }; indexByKeyPath[":id"] = result.primaryKey; if (keyPath != null) { indexByKeyPath[getKeyPathAlias(keyPath)] = result.primaryKey; } return result; }) }, hasGetAll: tables2.length > 0 && "getAll" in trans.objectStore(tables2[0]) && !(typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604) }; } function makeIDBKeyRange(range) { if (range.type === 3) return null; if (range.type === 4) throw new Error("Cannot convert never type to IDBKeyRange"); const { lower, upper, lowerOpen, upperOpen } = range; const idbRange = lower === void 0 ? upper === void 0 ? null : IdbKeyRange.upperBound(upper, !!upperOpen) : upper === void 0 ? IdbKeyRange.lowerBound(lower, !!lowerOpen) : IdbKeyRange.bound(lower, upper, !!lowerOpen, !!upperOpen); return idbRange; } function createDbCoreTable(tableSchema) { const tableName = tableSchema.name; function mutate({ trans, type: type2, keys: keys2, values, range }) { return new Promise((resolve, reject) => { resolve = wrap(resolve); const store = trans.objectStore(tableName); const outbound = store.keyPath == null; const isAddOrPut = type2 === "put" || type2 === "add"; if (!isAddOrPut && type2 !== "delete" && type2 !== "deleteRange") throw new Error("Invalid operation type: " + type2); const { length } = keys2 || values || { length: 1 }; if (keys2 && values && keys2.length !== values.length) { throw new Error("Given keys array must have same length as given values array."); } if (length === 0) return resolve({ numFailures: 0, failures: {}, results: [], lastResult: void 0 }); let req; const reqs = []; const failures = []; let numFailures = 0; const errorHandler = (event) => { ++numFailures; preventDefault(event); }; if (type2 === "deleteRange") { if (range.type === 4) return resolve({ numFailures, failures, results: [], lastResult: void 0 }); if (range.type === 3) reqs.push(req = store.clear()); else reqs.push(req = store.delete(makeIDBKeyRange(range))); } else { const [args1, args2] = isAddOrPut ? outbound ? [values, keys2] : [values, null] : [keys2, null]; if (isAddOrPut) { for (let i = 0; i < length; ++i) { reqs.push(req = args2 && args2[i] !== void 0 ? store[type2](args1[i], args2[i]) : store[type2](args1[i])); req.onerror = errorHandler; } } else { for (let i = 0; i < length; ++i) { reqs.push(req = store[type2](args1[i])); req.onerror = errorHandler; } } } const done = (event) => { const lastResult = event.target.result; reqs.forEach((req2, i) => req2.error != null && (failures[i] = req2.error)); resolve({ numFailures, failures, results: type2 === "delete" ? keys2 : reqs.map((req2) => req2.result), lastResult }); }; req.onerror = (event) => { errorHandler(event); done(event); }; req.onsuccess = done; }); } function openCursor2({ trans, values, query: query2, reverse, unique }) { return new Promise((resolve, reject) => { resolve = wrap(resolve); const { index, range } = query2; const store = trans.objectStore(tableName); const source = index.isPrimaryKey ? store : store.index(index.name); const direction = reverse ? unique ? "prevunique" : "prev" : unique ? "nextunique" : "next"; const req = values || !("openKeyCursor" in source) ? source.openCursor(makeIDBKeyRange(range), direction) : source.openKeyCursor(makeIDBKeyRange(range), direction); req.onerror = eventRejectHandler(reject); req.onsuccess = wrap((ev) => { const cursor = req.result; if (!cursor) { resolve(null); return; } cursor.___id = ++_id_counter; cursor.done = false; const _cursorContinue = cursor.continue.bind(cursor); let _cursorContinuePrimaryKey = cursor.continuePrimaryKey; if (_cursorContinuePrimaryKey) _cursorContinuePrimaryKey = _cursorContinuePrimaryKey.bind(cursor); const _cursorAdvance = cursor.advance.bind(cursor); const doThrowCursorIsNotStarted = () => { throw new Error("Cursor not started"); }; const doThrowCursorIsStopped = () => { throw new Error("Cursor not stopped"); }; cursor.trans = trans; cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsNotStarted; cursor.fail = wrap(reject); cursor.next = function() { let gotOne = 1; return this.start(() => gotOne-- ? this.continue() : this.stop()).then(() => this); }; cursor.start = (callback) => { const iterationPromise = new Promise((resolveIteration, rejectIteration) => { resolveIteration = wrap(resolveIteration); req.onerror = eventRejectHandler(rejectIteration); cursor.fail = rejectIteration; cursor.stop = (value) => { cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsStopped; resolveIteration(value); }; }); const guardedCallback = () => { if (req.result) { try { callback(); } catch (err) { cursor.fail(err); } } else { cursor.done = true; cursor.start = () => { throw new Error("Cursor behind last entry"); }; cursor.stop(); } }; req.onsuccess = wrap((ev2) => { req.onsuccess = guardedCallback; guardedCallback(); }); cursor.continue = _cursorContinue; cursor.continuePrimaryKey = _cursorContinuePrimaryKey; cursor.advance = _cursorAdvance; guardedCallback(); return iterationPromise; }; resolve(cursor); }, reject); }); } function query(hasGetAll2) { return (request) => { return new Promise((resolve, reject) => { resolve = wrap(resolve); const { trans, values, limit, query: query2 } = request; const nonInfinitLimit = limit === Infinity ? void 0 : limit; const { index, range } = query2; const store = trans.objectStore(tableName); const source = index.isPrimaryKey ? store : store.index(index.name); const idbKeyRange = makeIDBKeyRange(range); if (limit === 0) return resolve({ result: [] }); if (hasGetAll2) { const req = values ? source.getAll(idbKeyRange, nonInfinitLimit) : source.getAllKeys(idbKeyRange, nonInfinitLimit); req.onsuccess = (event) => resolve({ result: event.target.result }); req.onerror = eventRejectHandler(reject); } else { let count = 0; const req = values || !("openKeyCursor" in source) ? source.openCursor(idbKeyRange) : source.openKeyCursor(idbKeyRange); const result = []; req.onsuccess = (event) => { const cursor = req.result; if (!cursor) return resolve({ result }); result.push(values ? cursor.value : cursor.primaryKey); if (++count === limit) return resolve({ result }); cursor.continue(); }; req.onerror = eventRejectHandler(reject); } }); }; } return { name: tableName, schema: tableSchema, mutate, getMany({ trans, keys: keys2 }) { return new Promise((resolve, reject) => { resolve = wrap(resolve); const store = trans.objectStore(tableName); const length = keys2.length; const result = new Array(length); let keyCount = 0; let callbackCount = 0; let req; const successHandler = (event) => { const req2 = event.target; if ((result[req2._pos] = req2.result) != null) ; if (++callbackCount === keyCount) resolve(result); }; const errorHandler = eventRejectHandler(reject); for (let i = 0; i < length; ++i) { const key = keys2[i]; if (key != null) { req = store.get(keys2[i]); req._pos = i; req.onsuccess = successHandler; req.onerror = errorHandler; ++keyCount; } } if (keyCount === 0) resolve(result); }); }, get({ trans, key }) { return new Promise((resolve, reject) => { resolve = wrap(resolve); const store = trans.objectStore(tableName); const req = store.get(key); req.onsuccess = (event) => resolve(event.target.result); req.onerror = eventRejectHandler(reject); }); }, query: query(hasGetAll), openCursor: openCursor2, count({ query: query2, trans }) { const { index, range } = query2; return new Promise((resolve, reject) => { const store = trans.objectStore(tableName); const source = index.isPrimaryKey ? store : store.index(index.name); const idbKeyRange = makeIDBKeyRange(range); const req = idbKeyRange ? source.count(idbKeyRange) : source.count(); req.onsuccess = wrap((ev) => resolve(ev.target.result)); req.onerror = eventRejectHandler(reject); }); } }; } const { schema, hasGetAll } = extractSchema(db2, tmpTrans); const tables = schema.tables.map((tableSchema) => createDbCoreTable(tableSchema)); const tableMap = {}; tables.forEach((table) => tableMap[table.name] = table); return { stack: "dbcore", transaction: db2.transaction.bind(db2), table(name) { const result = tableMap[name]; if (!result) throw new Error(`Table '${name}' not found`); return tableMap[name]; }, MIN_KEY: -Infinity, MAX_KEY: getMaxKey(IdbKeyRange), schema }; } function createMiddlewareStack(stackImpl, middlewares) { return middlewares.reduce((down, { create }) => ({ ...down, ...create(down) }), stackImpl); } function createMiddlewareStacks(middlewares, idbdb, { IDBKeyRange, indexedDB: indexedDB2 }, tmpTrans) { const dbcore = createMiddlewareStack(createDBCore(idbdb, IDBKeyRange, tmpTrans), middlewares.dbcore); return { dbcore }; } function generateMiddlewareStacks({ _novip: db2 }, tmpTrans) { const idbdb = tmpTrans.db; const stacks = createMiddlewareStacks(db2._middlewares, idbdb, db2._deps, tmpTrans); db2.core = stacks.dbcore; db2.tables.forEach((table) => { const tableName = table.name; if (db2.core.schema.tables.some((tbl) => tbl.name === tableName)) { table.core = db2.core.table(tableName); if (db2[tableName] instanceof db2.Table) { db2[tableName].core = table.core; } } }); } function setApiOnPlace({ _novip: db2 }, objs, tableNames, dbschema) { tableNames.forEach((tableName) => { const schema = dbschema[tableName]; objs.forEach((obj) => { const propDesc = getPropertyDescriptor(obj, tableName); if (!propDesc || "value" in propDesc && propDesc.value === void 0) { if (obj === db2.Transaction.prototype || obj instanceof db2.Transaction) { setProp(obj, tableName, { get() { return this.table(tableName); }, set(value) { defineProperty(this, tableName, { value, writable: true, configurable: true, enumerable: true }); } }); } else { obj[tableName] = new db2.Table(tableName, schema); } } }); }); } function removeTablesApi({ _novip: db2 }, objs) { objs.forEach((obj) => { for (let key in obj) { if (obj[key] instanceof db2.Table) delete obj[key]; } }); } function lowerVersionFirst(a, b) { return a._cfg.version - b._cfg.version; } function runUpgraders(db2, oldVersion, idbUpgradeTrans, reject) { const globalSchema = db2._dbSchema; const trans = db2._createTransaction("readwrite", db2._storeNames, globalSchema); trans.create(idbUpgradeTrans); trans._completion.catch(reject); const rejectTransaction = trans._reject.bind(trans); const transless = PSD.transless || PSD; newScope(() => { PSD.trans = trans; PSD.transless = transless; if (oldVersion === 0) { keys(globalSchema).forEach((tableName) => { createTable(idbUpgradeTrans, tableName, globalSchema[tableName].primKey, globalSchema[tableName].indexes); }); generateMiddlewareStacks(db2, idbUpgradeTrans); DexiePromise.follow(() => db2.on.populate.fire(trans)).catch(rejectTransaction); } else updateTablesAndIndexes(db2, oldVersion, trans, idbUpgradeTrans).catch(rejectTransaction); }); } function updateTablesAndIndexes({ _novip: db2 }, oldVersion, trans, idbUpgradeTrans) { const queue = []; const versions = db2._versions; let globalSchema = db2._dbSchema = buildGlobalSchema(db2, db2.idbdb, idbUpgradeTrans); let anyContentUpgraderHasRun = false; const versToRun = versions.filter((v) => v._cfg.version >= oldVersion); versToRun.forEach((version) => { queue.push(() => { const oldSchema = globalSchema; const newSchema = version._cfg.dbschema; adjustToExistingIndexNames(db2, oldSchema, idbUpgradeTrans); adjustToExistingIndexNames(db2, newSchema, idbUpgradeTrans); globalSchema = db2._dbSchema = newSchema; const diff = getSchemaDiff(oldSchema, newSchema); diff.add.forEach((tuple) => { createTable(idbUpgradeTrans, tuple[0], tuple[1].primKey, tuple[1].indexes); }); diff.change.forEach((change) => { if (change.recreate) { throw new exceptions.Upgrade("Not yet support for changing primary key"); } else { const store = idbUpgradeTrans.objectStore(change.name); change.add.forEach((idx) => addIndex(store, idx)); change.change.forEach((idx) => { store.deleteIndex(idx.name); addIndex(store, idx); }); change.del.forEach((idxName) => store.deleteIndex(idxName)); } }); const contentUpgrade = version._cfg.contentUpgrade; if (contentUpgrade && version._cfg.version > oldVersion) { generateMiddlewareStacks(db2, idbUpgradeTrans); trans._memoizedTables = {}; anyContentUpgraderHasRun = true; let upgradeSchema = shallowClone(newSchema); diff.del.forEach((table) => { upgradeSchema[table] = oldSchema[table]; }); removeTablesApi(db2, [db2.Transaction.prototype]); setApiOnPlace(db2, [db2.Transaction.prototype], keys(upgradeSchema), upgradeSchema); trans.schema = upgradeSchema; const contentUpgradeIsAsync = isAsyncFunction(contentUpgrade); if (contentUpgradeIsAsync) { incrementExpectedAwaits(); } let returnValue; const promiseFollowed = DexiePromise.follow(() => { returnValue = contentUpgrade(trans); if (returnValue) { if (contentUpgradeIsAsync) { var decrementor = decrementExpectedAwaits.bind(null, null); returnValue.then(decrementor, decrementor); } } }); return returnValue && typeof returnValue.then === "function" ? DexiePromise.resolve(returnValue) : promiseFollowed.then(() => returnValue); } }); queue.push((idbtrans) => { if (!anyContentUpgraderHasRun || !hasIEDeleteObjectStoreBug) { const newSchema = version._cfg.dbschema; deleteRemovedTables(newSchema, idbtrans); } removeTablesApi(db2, [db2.Transaction.prototype]); setApiOnPlace(db2, [db2.Transaction.prototype], db2._storeNames, db2._dbSchema); trans.schema = db2._dbSchema; }); }); function runQueue() { return queue.length ? DexiePromise.resolve(queue.shift()(trans.idbtrans)).then(runQueue) : DexiePromise.resolve(); } return runQueue().then(() => { createMissingTables(globalSchema, idbUpgradeTrans); }); } function getSchemaDiff(oldSchema, newSchema) { const diff = { del: [], add: [], change: [] }; let table; for (table in oldSchema) { if (!newSchema[table]) diff.del.push(table); } for (table in newSchema) { const oldDef = oldSchema[table], newDef = newSchema[table]; if (!oldDef) { diff.add.push([table, newDef]); } else { const change = { name: table, def: newDef, recreate: false, del: [], add: [], change: [] }; if ("" + (oldDef.primKey.keyPath || "") !== "" + (newDef.primKey.keyPath || "") || oldDef.primKey.auto !== newDef.primKey.auto && !isIEOrEdge) { change.recreate = true; diff.change.push(change); } else { const oldIndexes = oldDef.idxByName; const newIndexes = newDef.idxByName; let idxName; for (idxName in oldIndexes) { if (!newIndexes[idxName]) change.del.push(idxName); } for (idxName in newIndexes) { const oldIdx = oldIndexes[idxName], newIdx = newIndexes[idxName]; if (!oldIdx) change.add.push(newIdx); else if (oldIdx.src !== newIdx.src) change.change.push(newIdx); } if (change.del.length > 0 || change.add.length > 0 || change.change.length > 0) { diff.change.push(change); } } } } return diff; } function createTable(idbtrans, tableName, primKey, indexes) { const store = idbtrans.db.createObjectStore(tableName, primKey.keyPath ? { keyPath: primKey.keyPath, autoIncrement: primKey.auto } : { autoIncrement: primKey.auto }); indexes.forEach((idx) => addIndex(store, idx)); return store; } function createMissingTables(newSchema, idbtrans) { keys(newSchema).forEach((tableName) => { if (!idbtrans.db.objectStoreNames.contains(tableName)) { createTable(idbtrans, tableName, newSchema[tableName].primKey, newSchema[tableName].indexes); } }); } function deleteRemovedTables(newSchema, idbtrans) { [].slice.call(idbtrans.db.objectStoreNames).forEach((storeName) => newSchema[storeName] == null && idbtrans.db.deleteObjectStore(storeName)); } function addIndex(store, idx) { store.createIndex(idx.name, idx.keyPath, { unique: idx.unique, multiEntry: idx.multi }); } function buildGlobalSchema(db2, idbdb, tmpTrans) { const globalSchema = {}; const dbStoreNames = slice(idbdb.objectStoreNames, 0); dbStoreNames.forEach((storeName) => { const store = tmpTrans.objectStore(storeName); let keyPath = store.keyPath; const primKey = createIndexSpec(nameFromKeyPath(keyPath), keyPath || "", false, false, !!store.autoIncrement, keyPath && typeof keyPath !== "string", true); const indexes = []; for (let j = 0; j < store.indexNames.length; ++j) { const idbindex = store.index(store.indexNames[j]); keyPath = idbindex.keyPath; var index = createIndexSpec(idbindex.name, keyPath, !!idbindex.unique, !!idbindex.multiEntry, false, keyPath && typeof keyPath !== "string", false); indexes.push(index); } globalSchema[storeName] = createTableSchema(storeName, primKey, indexes); }); return globalSchema; } function readGlobalSchema({ _novip: db2 }, idbdb, tmpTrans) { db2.verno = idbdb.version / 10; const globalSchema = db2._dbSchema = buildGlobalSchema(db2, idbdb, tmpTrans); db2._storeNames = slice(idbdb.objectStoreNames, 0); setApiOnPlace(db2, [db2._allTables], keys(globalSchema), globalSchema); } function verifyInstalledSchema(db2, tmpTrans) { const installedSchema = buildGlobalSchema(db2, db2.idbdb, tmpTrans); const diff = getSchemaDiff(installedSchema, db2._dbSchema); return !(diff.add.length || diff.change.some((ch) => ch.add.length || ch.change.length)); } function adjustToExistingIndexNames({ _novip: db2 }, schema, idbtrans) { const storeNames = idbtrans.db.objectStoreNames; for (let i = 0; i < storeNames.length; ++i) { const storeName = storeNames[i]; const store = idbtrans.objectStore(storeName); db2._hasGetAll = "getAll" in store; for (let j = 0; j < store.indexNames.length; ++j) { const indexName = store.indexNames[j]; const keyPath = store.index(indexName).keyPath; const dexieName = typeof keyPath === "string" ? keyPath : "[" + slice(keyPath).join("+") + "]"; if (schema[storeName]) { const indexSpec = schema[storeName].idxByName[dexieName]; if (indexSpec) { indexSpec.name = indexName; delete schema[storeName].idxByName[dexieName]; schema[storeName].idxByName[indexName] = indexSpec; } } } } if (typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && _global.WorkerGlobalScope && _global instanceof _global.WorkerGlobalScope && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604) { db2._hasGetAll = false; } } function parseIndexSyntax(primKeyAndIndexes) { return primKeyAndIndexes.split(",").map((index, indexNum) => { index = index.trim(); const name = index.replace(/([&*]|\+\+)/g, ""); const keyPath = /^\[/.test(name) ? name.match(/^\[(.*)\]$/)[1].split("+") : name; return createIndexSpec(name, keyPath || null, /\&/.test(index), /\*/.test(index), /\+\+/.test(index), isArray2(keyPath), indexNum === 0); }); } var Version2 = class { _parseStoresSpec(stores, outSchema) { keys(stores).forEach((tableName) => { if (stores[tableName] !== null) { var indexes = parseIndexSyntax(stores[tableName]); var primKey = indexes.shift(); if (primKey.multi) throw new exceptions.Schema("Primary key cannot be multi-valued"); indexes.forEach((idx) => { if (idx.auto) throw new exceptions.Schema("Only primary key can be marked as autoIncrement (++)"); if (!idx.keyPath) throw new exceptions.Schema("Index must have a name and cannot be an empty string"); }); outSchema[tableName] = createTableSchema(tableName, primKey, indexes); } }); } stores(stores) { const db2 = this.db; this._cfg.storesSource = this._cfg.storesSource ? extend(this._cfg.storesSource, stores) : stores; const versions = db2._versions; const storesSpec = {}; let dbschema = {}; versions.forEach((version) => { extend(storesSpec, version._cfg.storesSource); dbschema = version._cfg.dbschema = {}; version._parseStoresSpec(storesSpec, dbschema); }); db2._dbSchema = dbschema; removeTablesApi(db2, [db2._allTables, db2, db2.Transaction.prototype]); setApiOnPlace(db2, [db2._allTables, db2, db2.Transaction.prototype, this._cfg.tables], keys(dbschema), dbschema); db2._storeNames = keys(dbschema); return this; } upgrade(upgradeFunction) { this._cfg.contentUpgrade = promisableChain(this._cfg.contentUpgrade || nop, upgradeFunction); return this; } }; function createVersionConstructor(db2) { return makeClassConstructor(Version2.prototype, function Version3(versionNumber) { this.db = db2; this._cfg = { version: versionNumber, storesSource: null, dbschema: {}, tables: {}, contentUpgrade: null }; }); } function getDbNamesTable(indexedDB2, IDBKeyRange) { let dbNamesDB = indexedDB2["_dbNamesDB"]; if (!dbNamesDB) { dbNamesDB = indexedDB2["_dbNamesDB"] = new Dexie$1(DBNAMES_DB, { addons: [], indexedDB: indexedDB2, IDBKeyRange }); dbNamesDB.version(1).stores({ dbnames: "name" }); } return dbNamesDB.table("dbnames"); } function hasDatabasesNative(indexedDB2) { return indexedDB2 && typeof indexedDB2.databases === "function"; } function getDatabaseNames({ indexedDB: indexedDB2, IDBKeyRange }) { return hasDatabasesNative(indexedDB2) ? Promise.resolve(indexedDB2.databases()).then((infos) => infos.map((info) => info.name).filter((name) => name !== DBNAMES_DB)) : getDbNamesTable(indexedDB2, IDBKeyRange).toCollection().primaryKeys(); } function _onDatabaseCreated({ indexedDB: indexedDB2, IDBKeyRange }, name) { !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).put({ name }).catch(nop); } function _onDatabaseDeleted({ indexedDB: indexedDB2, IDBKeyRange }, name) { !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).delete(name).catch(nop); } function vip(fn) { return newScope(function() { PSD.letThrough = true; return fn(); }); } function idbReady() { var isSafari = !navigator.userAgentData && /Safari\//.test(navigator.userAgent) && !/Chrom(e|ium)\//.test(navigator.userAgent); if (!isSafari || !indexedDB.databases) return Promise.resolve(); var intervalId; return new Promise(function(resolve) { var tryIdb = function() { return indexedDB.databases().finally(resolve); }; intervalId = setInterval(tryIdb, 100); tryIdb(); }).finally(function() { return clearInterval(intervalId); }); } function dexieOpen(db2) { const state = db2._state; const { indexedDB: indexedDB2 } = db2._deps; if (state.isBeingOpened || db2.idbdb) return state.dbReadyPromise.then(() => state.dbOpenError ? rejection(state.dbOpenError) : db2); debug && (state.openCanceller._stackHolder = getErrorWithStack()); state.isBeingOpened = true; state.dbOpenError = null; state.openComplete = false; const openCanceller = state.openCanceller; function throwIfCancelled() { if (state.openCanceller !== openCanceller) throw new exceptions.DatabaseClosed("db.open() was cancelled"); } let resolveDbReady = state.dbReadyResolve, upgradeTransaction = null, wasCreated = false; const tryOpenDB = () => new DexiePromise((resolve, reject) => { throwIfCancelled(); if (!indexedDB2) throw new exceptions.MissingAPI(); const dbName = db2.name; const req = state.autoSchema ? indexedDB2.open(dbName) : indexedDB2.open(dbName, Math.round(db2.verno * 10)); if (!req) throw new exceptions.MissingAPI(); req.onerror = eventRejectHandler(reject); req.onblocked = wrap(db2._fireOnBlocked); req.onupgradeneeded = wrap((e) => { upgradeTransaction = req.transaction; if (state.autoSchema && !db2._options.allowEmptyDB) { req.onerror = preventDefault; upgradeTransaction.abort(); req.result.close(); const delreq = indexedDB2.deleteDatabase(dbName); delreq.onsuccess = delreq.onerror = wrap(() => { reject(new exceptions.NoSuchDatabase(`Database ${dbName} doesnt exist`)); }); } else { upgradeTransaction.onerror = eventRejectHandler(reject); var oldVer = e.oldVersion > Math.pow(2, 62) ? 0 : e.oldVersion; wasCreated = oldVer < 1; db2._novip.idbdb = req.result; runUpgraders(db2, oldVer / 10, upgradeTransaction, reject); } }, reject); req.onsuccess = wrap(() => { upgradeTransaction = null; const idbdb = db2._novip.idbdb = req.result; const objectStoreNames = slice(idbdb.objectStoreNames); if (objectStoreNames.length > 0) try { const tmpTrans = idbdb.transaction(safariMultiStoreFix(objectStoreNames), "readonly"); if (state.autoSchema) readGlobalSchema(db2, idbdb, tmpTrans); else { adjustToExistingIndexNames(db2, db2._dbSchema, tmpTrans); if (!verifyInstalledSchema(db2, tmpTrans)) { console.warn(`Dexie SchemaDiff: Schema was extended without increasing the number passed to db.version(). Some queries may fail.`); } } generateMiddlewareStacks(db2, tmpTrans); } catch (e) { } connections.push(db2); idbdb.onversionchange = wrap((ev) => { state.vcFired = true; db2.on("versionchange").fire(ev); }); idbdb.onclose = wrap((ev) => { db2.on("close").fire(ev); }); if (wasCreated) _onDatabaseCreated(db2._deps, dbName); resolve(); }, reject); }).catch((err) => { if (err && err.name === "UnknownError" && state.PR1398_maxLoop > 0) { state.PR1398_maxLoop--; console.warn("Dexie: Workaround for Chrome UnknownError on open()"); return tryOpenDB(); } else { return DexiePromise.reject(err); } }); return DexiePromise.race([ openCanceller, (typeof navigator === "undefined" ? DexiePromise.resolve() : idbReady()).then(tryOpenDB) ]).then(() => { throwIfCancelled(); state.onReadyBeingFired = []; return DexiePromise.resolve(vip(() => db2.on.ready.fire(db2.vip))).then(function fireRemainders() { if (state.onReadyBeingFired.length > 0) { let remainders = state.onReadyBeingFired.reduce(promisableChain, nop); state.onReadyBeingFired = []; return DexiePromise.resolve(vip(() => remainders(db2.vip))).then(fireRemainders); } }); }).finally(() => { state.onReadyBeingFired = null; state.isBeingOpened = false; }).then(() => { return db2; }).catch((err) => { state.dbOpenError = err; try { upgradeTransaction && upgradeTransaction.abort(); } catch (_a) { } if (openCanceller === state.openCanceller) { db2._close(); } return rejection(err); }).finally(() => { state.openComplete = true; resolveDbReady(); }); } function awaitIterator(iterator) { var callNext = (result) => iterator.next(result), doThrow = (error) => iterator.throw(error), onSuccess = step(callNext), onError = step(doThrow); function step(getNext) { return (val) => { var next = getNext(val), value = next.value; return next.done ? value : !value || typeof value.then !== "function" ? isArray2(value) ? Promise.all(value).then(onSuccess, onError) : onSuccess(value) : value.then(onSuccess, onError); }; } return step(callNext)(); } function extractTransactionArgs(mode, _tableArgs_, scopeFunc) { var i = arguments.length; if (i < 2) throw new exceptions.InvalidArgument("Too few arguments"); var args = new Array(i - 1); while (--i) args[i - 1] = arguments[i]; scopeFunc = args.pop(); var tables = flatten(args); return [mode, tables, scopeFunc]; } function enterTransactionScope(db2, mode, storeNames, parentTransaction, scopeFunc) { return DexiePromise.resolve().then(() => { const transless = PSD.transless || PSD; const trans = db2._createTransaction(mode, storeNames, db2._dbSchema, parentTransaction); const zoneProps = { trans, transless }; if (parentTransaction) { trans.idbtrans = parentTransaction.idbtrans; } else { try { trans.create(); db2._state.PR1398_maxLoop = 3; } catch (ex) { if (ex.name === errnames.InvalidState && db2.isOpen() && --db2._state.PR1398_maxLoop > 0) { console.warn("Dexie: Need to reopen db"); db2._close(); return db2.open().then(() => enterTransactionScope(db2, mode, storeNames, null, scopeFunc)); } return rejection(ex); } } const scopeFuncIsAsync = isAsyncFunction(scopeFunc); if (scopeFuncIsAsync) { incrementExpectedAwaits(); } let returnValue; const promiseFollowed = DexiePromise.follow(() => { returnValue = scopeFunc.call(trans, trans); if (returnValue) { if (scopeFuncIsAsync) { var decrementor = decrementExpectedAwaits.bind(null, null); returnValue.then(decrementor, decrementor); } else if (typeof returnValue.next === "function" && typeof returnValue.throw === "function") { returnValue = awaitIterator(returnValue); } } }, zoneProps); return (returnValue && typeof returnValue.then === "function" ? DexiePromise.resolve(returnValue).then((x) => trans.active ? x : rejection(new exceptions.PrematureCommit("Transaction committed too early. See http://bit.ly/2kdckMn"))) : promiseFollowed.then(() => returnValue)).then((x) => { if (parentTransaction) trans._resolve(); return trans._completion.then(() => x); }).catch((e) => { trans._reject(e); return rejection(e); }); }); } function pad(a, value, count) { const result = isArray2(a) ? a.slice() : [a]; for (let i = 0; i < count; ++i) result.push(value); return result; } function createVirtualIndexMiddleware(down) { return { ...down, table(tableName) { const table = down.table(tableName); const { schema } = table; const indexLookup = {}; const allVirtualIndexes = []; function addVirtualIndexes(keyPath, keyTail, lowLevelIndex) { const keyPathAlias = getKeyPathAlias(keyPath); const indexList = indexLookup[keyPathAlias] = indexLookup[keyPathAlias] || []; const keyLength = keyPath == null ? 0 : typeof keyPath === "string" ? 1 : keyPath.length; const isVirtual = keyTail > 0; const virtualIndex = { ...lowLevelIndex, isVirtual, keyTail, keyLength, extractKey: getKeyExtractor(keyPath), unique: !isVirtual && lowLevelIndex.unique }; indexList.push(virtualIndex); if (!virtualIndex.isPrimaryKey) { allVirtualIndexes.push(virtualIndex); } if (keyLength > 1) { const virtualKeyPath = keyLength === 2 ? keyPath[0] : keyPath.slice(0, keyLength - 1); addVirtualIndexes(virtualKeyPath, keyTail + 1, lowLevelIndex); } indexList.sort((a, b) => a.keyTail - b.keyTail); return virtualIndex; } const primaryKey = addVirtualIndexes(schema.primaryKey.keyPath, 0, schema.primaryKey); indexLookup[":id"] = [primaryKey]; for (const index of schema.indexes) { addVirtualIndexes(index.keyPath, 0, index); } function findBestIndex(keyPath) { const result2 = indexLookup[getKeyPathAlias(keyPath)]; return result2 && result2[0]; } function translateRange(range, keyTail) { return { type: range.type === 1 ? 2 : range.type, lower: pad(range.lower, range.lowerOpen ? down.MAX_KEY : down.MIN_KEY, keyTail), lowerOpen: true, upper: pad(range.upper, range.upperOpen ? down.MIN_KEY : down.MAX_KEY, keyTail), upperOpen: true }; } function translateRequest(req) { const index = req.query.index; return index.isVirtual ? { ...req, query: { index, range: translateRange(req.query.range, index.keyTail) } } : req; } const result = { ...table, schema: { ...schema, primaryKey, indexes: allVirtualIndexes, getIndexByKeyPath: findBestIndex }, count(req) { return table.count(translateRequest(req)); }, query(req) { return table.query(translateRequest(req)); }, openCursor(req) { const { keyTail, isVirtual, keyLength } = req.query.index; if (!isVirtual) return table.openCursor(req); function createVirtualCursor(cursor) { function _continue(key) { key != null ? cursor.continue(pad(key, req.reverse ? down.MAX_KEY : down.MIN_KEY, keyTail)) : req.unique ? cursor.continue(cursor.key.slice(0, keyLength).concat(req.reverse ? down.MIN_KEY : down.MAX_KEY, keyTail)) : cursor.continue(); } const virtualCursor = Object.create(cursor, { continue: { value: _continue }, continuePrimaryKey: { value(key, primaryKey2) { cursor.continuePrimaryKey(pad(key, down.MAX_KEY, keyTail), primaryKey2); } }, primaryKey: { get() { return cursor.primaryKey; } }, key: { get() { const key = cursor.key; return keyLength === 1 ? key[0] : key.slice(0, keyLength); } }, value: { get() { return cursor.value; } } }); return virtualCursor; } return table.openCursor(translateRequest(req)).then((cursor) => cursor && createVirtualCursor(cursor)); } }; return result; } }; } var virtualIndexMiddleware = { stack: "dbcore", name: "VirtualIndexMiddleware", level: 1, create: createVirtualIndexMiddleware }; function getObjectDiff(a, b, rv, prfx) { rv = rv || {}; prfx = prfx || ""; keys(a).forEach((prop) => { if (!hasOwn(b, prop)) { rv[prfx + prop] = void 0; } else { var ap = a[prop], bp = b[prop]; if (typeof ap === "object" && typeof bp === "object" && ap && bp) { const apTypeName = toStringTag(ap); const bpTypeName = toStringTag(bp); if (apTypeName !== bpTypeName) { rv[prfx + prop] = b[prop]; } else if (apTypeName === "Object") { getObjectDiff(ap, bp, rv, prfx + prop + "."); } else if (ap !== bp) { rv[prfx + prop] = b[prop]; } } else if (ap !== bp) rv[prfx + prop] = b[prop]; } }); keys(b).forEach((prop) => { if (!hasOwn(a, prop)) { rv[prfx + prop] = b[prop]; } }); return rv; } function getEffectiveKeys(primaryKey, req) { if (req.type === "delete") return req.keys; return req.keys || req.values.map(primaryKey.extractKey); } var hooksMiddleware = { stack: "dbcore", name: "HooksMiddleware", level: 2, create: (downCore) => ({ ...downCore, table(tableName) { const downTable = downCore.table(tableName); const { primaryKey } = downTable.schema; const tableMiddleware = { ...downTable, mutate(req) { const dxTrans = PSD.trans; const { deleting, creating, updating } = dxTrans.table(tableName).hook; switch (req.type) { case "add": if (creating.fire === nop) break; return dxTrans._promise("readwrite", () => addPutOrDelete(req), true); case "put": if (creating.fire === nop && updating.fire === nop) break; return dxTrans._promise("readwrite", () => addPutOrDelete(req), true); case "delete": if (deleting.fire === nop) break; return dxTrans._promise("readwrite", () => addPutOrDelete(req), true); case "deleteRange": if (deleting.fire === nop) break; return dxTrans._promise("readwrite", () => deleteRange(req), true); } return downTable.mutate(req); function addPutOrDelete(req2) { const dxTrans2 = PSD.trans; const keys2 = req2.keys || getEffectiveKeys(primaryKey, req2); if (!keys2) throw new Error("Keys missing"); req2 = req2.type === "add" || req2.type === "put" ? { ...req2, keys: keys2 } : { ...req2 }; if (req2.type !== "delete") req2.values = [...req2.values]; if (req2.keys) req2.keys = [...req2.keys]; return getExistingValues(downTable, req2, keys2).then((existingValues) => { const contexts = keys2.map((key, i) => { const existingValue = existingValues[i]; const ctx = { onerror: null, onsuccess: null }; if (req2.type === "delete") { deleting.fire.call(ctx, key, existingValue, dxTrans2); } else if (req2.type === "add" || existingValue === void 0) { const generatedPrimaryKey = creating.fire.call(ctx, key, req2.values[i], dxTrans2); if (key == null && generatedPrimaryKey != null) { key = generatedPrimaryKey; req2.keys[i] = key; if (!primaryKey.outbound) { setByKeyPath(req2.values[i], primaryKey.keyPath, key); } } } else { const objectDiff = getObjectDiff(existingValue, req2.values[i]); const additionalChanges = updating.fire.call(ctx, objectDiff, key, existingValue, dxTrans2); if (additionalChanges) { const requestedValue = req2.values[i]; Object.keys(additionalChanges).forEach((keyPath) => { if (hasOwn(requestedValue, keyPath)) { requestedValue[keyPath] = additionalChanges[keyPath]; } else { setByKeyPath(requestedValue, keyPath, additionalChanges[keyPath]); } }); } } return ctx; }); return downTable.mutate(req2).then(({ failures, results, numFailures, lastResult }) => { for (let i = 0; i < keys2.length; ++i) { const primKey = results ? results[i] : keys2[i]; const ctx = contexts[i]; if (primKey == null) { ctx.onerror && ctx.onerror(failures[i]); } else { ctx.onsuccess && ctx.onsuccess( req2.type === "put" && existingValues[i] ? req2.values[i] : primKey ); } } return { failures, results, numFailures, lastResult }; }).catch((error) => { contexts.forEach((ctx) => ctx.onerror && ctx.onerror(error)); return Promise.reject(error); }); }); } function deleteRange(req2) { return deleteNextChunk(req2.trans, req2.range, 1e4); } function deleteNextChunk(trans, range, limit) { return downTable.query({ trans, values: false, query: { index: primaryKey, range }, limit }).then(({ result }) => { return addPutOrDelete({ type: "delete", keys: result, trans }).then((res) => { if (res.numFailures > 0) return Promise.reject(res.failures[0]); if (result.length < limit) { return { failures: [], numFailures: 0, lastResult: void 0 }; } else { return deleteNextChunk(trans, { ...range, lower: result[result.length - 1], lowerOpen: true }, limit); } }); }); } } }; return tableMiddleware; } }) }; function getExistingValues(table, req, effectiveKeys) { return req.type === "add" ? Promise.resolve([]) : table.getMany({ trans: req.trans, keys: effectiveKeys, cache: "immutable" }); } function getFromTransactionCache(keys2, cache, clone) { try { if (!cache) return null; if (cache.keys.length < keys2.length) return null; const result = []; for (let i = 0, j = 0; i < cache.keys.length && j < keys2.length; ++i) { if (cmp(cache.keys[i], keys2[j]) !== 0) continue; result.push(clone ? deepClone(cache.values[i]) : cache.values[i]); ++j; } return result.length === keys2.length ? result : null; } catch (_a) { return null; } } var cacheExistingValuesMiddleware = { stack: "dbcore", level: -1, create: (core) => { return { table: (tableName) => { const table = core.table(tableName); return { ...table, getMany: (req) => { if (!req.cache) { return table.getMany(req); } const cachedResult = getFromTransactionCache(req.keys, req.trans["_cache"], req.cache === "clone"); if (cachedResult) { return DexiePromise.resolve(cachedResult); } return table.getMany(req).then((res) => { req.trans["_cache"] = { keys: req.keys, values: req.cache === "clone" ? deepClone(res) : res }; return res; }); }, mutate: (req) => { if (req.type !== "add") req.trans["_cache"] = null; return table.mutate(req); } }; } }; } }; function isEmptyRange(node) { return !("from" in node); } var RangeSet = function(fromOrTree, to) { if (this) { extend(this, arguments.length ? { d: 1, from: fromOrTree, to: arguments.length > 1 ? to : fromOrTree } : { d: 0 }); } else { const rv = new RangeSet(); if (fromOrTree && "d" in fromOrTree) { extend(rv, fromOrTree); } return rv; } }; props(RangeSet.prototype, { add(rangeSet) { mergeRanges(this, rangeSet); return this; }, addKey(key) { addRange(this, key, key); return this; }, addKeys(keys2) { keys2.forEach((key) => addRange(this, key, key)); return this; }, [iteratorSymbol]() { return getRangeSetIterator(this); } }); function addRange(target, from, to) { const diff = cmp(from, to); if (isNaN(diff)) return; if (diff > 0) throw RangeError(); if (isEmptyRange(target)) return extend(target, { from, to, d: 1 }); const left = target.l; const right = target.r; if (cmp(to, target.from) < 0) { left ? addRange(left, from, to) : target.l = { from, to, d: 1, l: null, r: null }; return rebalance(target); } if (cmp(from, target.to) > 0) { right ? addRange(right, from, to) : target.r = { from, to, d: 1, l: null, r: null }; return rebalance(target); } if (cmp(from, target.from) < 0) { target.from = from; target.l = null; target.d = right ? right.d + 1 : 1; } if (cmp(to, target.to) > 0) { target.to = to; target.r = null; target.d = target.l ? target.l.d + 1 : 1; } const rightWasCutOff = !target.r; if (left && !target.l) { mergeRanges(target, left); } if (right && rightWasCutOff) { mergeRanges(target, right); } } function mergeRanges(target, newSet) { function _addRangeSet(target2, { from, to, l, r }) { addRange(target2, from, to); if (l) _addRangeSet(target2, l); if (r) _addRangeSet(target2, r); } if (!isEmptyRange(newSet)) _addRangeSet(target, newSet); } function rangesOverlap(rangeSet1, rangeSet2) { const i1 = getRangeSetIterator(rangeSet2); let nextResult1 = i1.next(); if (nextResult1.done) return false; let a = nextResult1.value; const i2 = getRangeSetIterator(rangeSet1); let nextResult2 = i2.next(a.from); let b = nextResult2.value; while (!nextResult1.done && !nextResult2.done) { if (cmp(b.from, a.to) <= 0 && cmp(b.to, a.from) >= 0) return true; cmp(a.from, b.from) < 0 ? a = (nextResult1 = i1.next(b.from)).value : b = (nextResult2 = i2.next(a.from)).value; } return false; } function getRangeSetIterator(node) { let state = isEmptyRange(node) ? null : { s: 0, n: node }; return { next(key) { const keyProvided = arguments.length > 0; while (state) { switch (state.s) { case 0: state.s = 1; if (keyProvided) { while (state.n.l && cmp(key, state.n.from) < 0) state = { up: state, n: state.n.l, s: 1 }; } else { while (state.n.l) state = { up: state, n: state.n.l, s: 1 }; } case 1: state.s = 2; if (!keyProvided || cmp(key, state.n.to) <= 0) return { value: state.n, done: false }; case 2: if (state.n.r) { state.s = 3; state = { up: state, n: state.n.r, s: 0 }; continue; } case 3: state = state.up; } } return { done: true }; } }; } function rebalance(target) { var _a, _b; const diff = (((_a = target.r) === null || _a === void 0 ? void 0 : _a.d) || 0) - (((_b = target.l) === null || _b === void 0 ? void 0 : _b.d) || 0); const r = diff > 1 ? "r" : diff < -1 ? "l" : ""; if (r) { const l = r === "r" ? "l" : "r"; const rootClone = { ...target }; const oldRootRight = target[r]; target.from = oldRootRight.from; target.to = oldRootRight.to; target[r] = oldRootRight[r]; rootClone[r] = oldRootRight[l]; target[l] = rootClone; rootClone.d = computeDepth(rootClone); } target.d = computeDepth(target); } function computeDepth({ r, l }) { return (r ? l ? Math.max(r.d, l.d) : r.d : l ? l.d : 0) + 1; } var observabilityMiddleware = { stack: "dbcore", level: 0, create: (core) => { const dbName = core.schema.name; const FULL_RANGE = new RangeSet(core.MIN_KEY, core.MAX_KEY); return { ...core, table: (tableName) => { const table = core.table(tableName); const { schema } = table; const { primaryKey } = schema; const { extractKey, outbound } = primaryKey; const tableClone = { ...table, mutate: (req) => { const trans = req.trans; const mutatedParts = trans.mutatedParts || (trans.mutatedParts = {}); const getRangeSet = (indexName) => { const part = `idb://${dbName}/${tableName}/${indexName}`; return mutatedParts[part] || (mutatedParts[part] = new RangeSet()); }; const pkRangeSet = getRangeSet(""); const delsRangeSet = getRangeSet(":dels"); const { type: type2 } = req; let [keys2, newObjs] = req.type === "deleteRange" ? [req.range] : req.type === "delete" ? [req.keys] : req.values.length < 50 ? [[], req.values] : []; const oldCache = req.trans["_cache"]; return table.mutate(req).then((res) => { if (isArray2(keys2)) { if (type2 !== "delete") keys2 = res.results; pkRangeSet.addKeys(keys2); const oldObjs = getFromTransactionCache(keys2, oldCache); if (!oldObjs && type2 !== "add") { delsRangeSet.addKeys(keys2); } if (oldObjs || newObjs) { trackAffectedIndexes(getRangeSet, schema, oldObjs, newObjs); } } else if (keys2) { const range = { from: keys2.lower, to: keys2.upper }; delsRangeSet.add(range); pkRangeSet.add(range); } else { pkRangeSet.add(FULL_RANGE); delsRangeSet.add(FULL_RANGE); schema.indexes.forEach((idx) => getRangeSet(idx.name).add(FULL_RANGE)); } return res; }); } }; const getRange = ({ query: { index, range } }) => { var _a, _b; return [ index, new RangeSet((_a = range.lower) !== null && _a !== void 0 ? _a : core.MIN_KEY, (_b = range.upper) !== null && _b !== void 0 ? _b : core.MAX_KEY) ]; }; const readSubscribers = { get: (req) => [primaryKey, new RangeSet(req.key)], getMany: (req) => [primaryKey, new RangeSet().addKeys(req.keys)], count: getRange, query: getRange, openCursor: getRange }; keys(readSubscribers).forEach((method) => { tableClone[method] = function(req) { const { subscr } = PSD; if (subscr) { const getRangeSet = (indexName) => { const part = `idb://${dbName}/${tableName}/${indexName}`; return subscr[part] || (subscr[part] = new RangeSet()); }; const pkRangeSet = getRangeSet(""); const delsRangeSet = getRangeSet(":dels"); const [queriedIndex, queriedRanges] = readSubscribers[method](req); getRangeSet(queriedIndex.name || "").add(queriedRanges); if (!queriedIndex.isPrimaryKey) { if (method === "count") { delsRangeSet.add(FULL_RANGE); } else { const keysPromise = method === "query" && outbound && req.values && table.query({ ...req, values: false }); return table[method].apply(this, arguments).then((res) => { if (method === "query") { if (outbound && req.values) { return keysPromise.then(({ result: resultingKeys }) => { pkRangeSet.addKeys(resultingKeys); return res; }); } const pKeys = req.values ? res.result.map(extractKey) : res.result; if (req.values) { pkRangeSet.addKeys(pKeys); } else { delsRangeSet.addKeys(pKeys); } } else if (method === "openCursor") { const cursor = res; const wantValues = req.values; return cursor && Object.create(cursor, { key: { get() { delsRangeSet.addKey(cursor.primaryKey); return cursor.key; } }, primaryKey: { get() { const pkey = cursor.primaryKey; delsRangeSet.addKey(pkey); return pkey; } }, value: { get() { wantValues && pkRangeSet.addKey(cursor.primaryKey); return cursor.value; } } }); } return res; }); } } } return table[method].apply(this, arguments); }; }); return tableClone; } }; } }; function trackAffectedIndexes(getRangeSet, schema, oldObjs, newObjs) { function addAffectedIndex(ix) { const rangeSet = getRangeSet(ix.name || ""); function extractKey(obj) { return obj != null ? ix.extractKey(obj) : null; } const addKeyOrKeys = (key) => ix.multiEntry && isArray2(key) ? key.forEach((key2) => rangeSet.addKey(key2)) : rangeSet.addKey(key); (oldObjs || newObjs).forEach((_, i) => { const oldKey = oldObjs && extractKey(oldObjs[i]); const newKey = newObjs && extractKey(newObjs[i]); if (cmp(oldKey, newKey) !== 0) { if (oldKey != null) addKeyOrKeys(oldKey); if (newKey != null) addKeyOrKeys(newKey); } }); } schema.indexes.forEach(addAffectedIndex); } var Dexie$1 = class _Dexie$1 { constructor(name, options) { this._middlewares = {}; this.verno = 0; const deps = _Dexie$1.dependencies; this._options = options = { addons: _Dexie$1.addons, autoOpen: true, indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange, ...options }; this._deps = { indexedDB: options.indexedDB, IDBKeyRange: options.IDBKeyRange }; const { addons } = options; this._dbSchema = {}; this._versions = []; this._storeNames = []; this._allTables = {}; this.idbdb = null; this._novip = this; const state = { dbOpenError: null, isBeingOpened: false, onReadyBeingFired: null, openComplete: false, dbReadyResolve: nop, dbReadyPromise: null, cancelOpen: nop, openCanceller: null, autoSchema: true, PR1398_maxLoop: 3 }; state.dbReadyPromise = new DexiePromise((resolve) => { state.dbReadyResolve = resolve; }); state.openCanceller = new DexiePromise((_, reject) => { state.cancelOpen = reject; }); this._state = state; this.name = name; this.on = Events(this, "populate", "blocked", "versionchange", "close", { ready: [promisableChain, nop] }); this.on.ready.subscribe = override(this.on.ready.subscribe, (subscribe) => { return (subscriber, bSticky) => { _Dexie$1.vip(() => { const state2 = this._state; if (state2.openComplete) { if (!state2.dbOpenError) DexiePromise.resolve().then(subscriber); if (bSticky) subscribe(subscriber); } else if (state2.onReadyBeingFired) { state2.onReadyBeingFired.push(subscriber); if (bSticky) subscribe(subscriber); } else { subscribe(subscriber); const db2 = this; if (!bSticky) subscribe(function unsubscribe() { db2.on.ready.unsubscribe(subscriber); db2.on.ready.unsubscribe(unsubscribe); }); } }); }; }); this.Collection = createCollectionConstructor(this); this.Table = createTableConstructor(this); this.Transaction = createTransactionConstructor(this); this.Version = createVersionConstructor(this); this.WhereClause = createWhereClauseConstructor(this); this.on("versionchange", (ev) => { if (ev.newVersion > 0) console.warn(`Another connection wants to upgrade database '${this.name}'. Closing db now to resume the upgrade.`); else console.warn(`Another connection wants to delete database '${this.name}'. Closing db now to resume the delete request.`); this.close(); }); this.on("blocked", (ev) => { if (!ev.newVersion || ev.newVersion < ev.oldVersion) console.warn(`Dexie.delete('${this.name}') was blocked`); else console.warn(`Upgrade '${this.name}' blocked by other connection holding version ${ev.oldVersion / 10}`); }); this._maxKey = getMaxKey(options.IDBKeyRange); this._createTransaction = (mode, storeNames, dbschema, parentTransaction) => new this.Transaction(mode, storeNames, dbschema, this._options.chromeTransactionDurability, parentTransaction); this._fireOnBlocked = (ev) => { this.on("blocked").fire(ev); connections.filter((c) => c.name === this.name && c !== this && !c._state.vcFired).map((c) => c.on("versionchange").fire(ev)); }; this.use(virtualIndexMiddleware); this.use(hooksMiddleware); this.use(observabilityMiddleware); this.use(cacheExistingValuesMiddleware); this.vip = Object.create(this, { _vip: { value: true } }); addons.forEach((addon) => addon(this)); } version(versionNumber) { if (isNaN(versionNumber) || versionNumber < 0.1) throw new exceptions.Type(`Given version is not a positive number`); versionNumber = Math.round(versionNumber * 10) / 10; if (this.idbdb || this._state.isBeingOpened) throw new exceptions.Schema("Cannot add version when database is open"); this.verno = Math.max(this.verno, versionNumber); const versions = this._versions; var versionInstance = versions.filter((v) => v._cfg.version === versionNumber)[0]; if (versionInstance) return versionInstance; versionInstance = new this.Version(versionNumber); versions.push(versionInstance); versions.sort(lowerVersionFirst); versionInstance.stores({}); this._state.autoSchema = false; return versionInstance; } _whenReady(fn) { return this.idbdb && (this._state.openComplete || PSD.letThrough || this._vip) ? fn() : new DexiePromise((resolve, reject) => { if (this._state.openComplete) { return reject(new exceptions.DatabaseClosed(this._state.dbOpenError)); } if (!this._state.isBeingOpened) { if (!this._options.autoOpen) { reject(new exceptions.DatabaseClosed()); return; } this.open().catch(nop); } this._state.dbReadyPromise.then(resolve, reject); }).then(fn); } use({ stack, create, level, name }) { if (name) this.unuse({ stack, name }); const middlewares = this._middlewares[stack] || (this._middlewares[stack] = []); middlewares.push({ stack, create, level: level == null ? 10 : level, name }); middlewares.sort((a, b) => a.level - b.level); return this; } unuse({ stack, name, create }) { if (stack && this._middlewares[stack]) { this._middlewares[stack] = this._middlewares[stack].filter((mw) => create ? mw.create !== create : name ? mw.name !== name : false); } return this; } open() { return dexieOpen(this); } _close() { const state = this._state; const idx = connections.indexOf(this); if (idx >= 0) connections.splice(idx, 1); if (this.idbdb) { try { this.idbdb.close(); } catch (e) { } this._novip.idbdb = null; } state.dbReadyPromise = new DexiePromise((resolve) => { state.dbReadyResolve = resolve; }); state.openCanceller = new DexiePromise((_, reject) => { state.cancelOpen = reject; }); } close() { this._close(); const state = this._state; this._options.autoOpen = false; state.dbOpenError = new exceptions.DatabaseClosed(); if (state.isBeingOpened) state.cancelOpen(state.dbOpenError); } delete() { const hasArguments = arguments.length > 0; const state = this._state; return new DexiePromise((resolve, reject) => { const doDelete = () => { this.close(); var req = this._deps.indexedDB.deleteDatabase(this.name); req.onsuccess = wrap(() => { _onDatabaseDeleted(this._deps, this.name); resolve(); }); req.onerror = eventRejectHandler(reject); req.onblocked = this._fireOnBlocked; }; if (hasArguments) throw new exceptions.InvalidArgument("Arguments not allowed in db.delete()"); if (state.isBeingOpened) { state.dbReadyPromise.then(doDelete); } else { doDelete(); } }); } backendDB() { return this.idbdb; } isOpen() { return this.idbdb !== null; } hasBeenClosed() { const dbOpenError = this._state.dbOpenError; return dbOpenError && dbOpenError.name === "DatabaseClosed"; } hasFailed() { return this._state.dbOpenError !== null; } dynamicallyOpened() { return this._state.autoSchema; } get tables() { return keys(this._allTables).map((name) => this._allTables[name]); } transaction() { const args = extractTransactionArgs.apply(this, arguments); return this._transaction.apply(this, args); } _transaction(mode, tables, scopeFunc) { let parentTransaction = PSD.trans; if (!parentTransaction || parentTransaction.db !== this || mode.indexOf("!") !== -1) parentTransaction = null; const onlyIfCompatible = mode.indexOf("?") !== -1; mode = mode.replace("!", "").replace("?", ""); let idbMode, storeNames; try { storeNames = tables.map((table) => { var storeName = table instanceof this.Table ? table.name : table; if (typeof storeName !== "string") throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed"); return storeName; }); if (mode == "r" || mode === READONLY) idbMode = READONLY; else if (mode == "rw" || mode == READWRITE) idbMode = READWRITE; else throw new exceptions.InvalidArgument("Invalid transaction mode: " + mode); if (parentTransaction) { if (parentTransaction.mode === READONLY && idbMode === READWRITE) { if (onlyIfCompatible) { parentTransaction = null; } else throw new exceptions.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY"); } if (parentTransaction) { storeNames.forEach((storeName) => { if (parentTransaction && parentTransaction.storeNames.indexOf(storeName) === -1) { if (onlyIfCompatible) { parentTransaction = null; } else throw new exceptions.SubTransaction("Table " + storeName + " not included in parent transaction."); } }); } if (onlyIfCompatible && parentTransaction && !parentTransaction.active) { parentTransaction = null; } } } catch (e) { return parentTransaction ? parentTransaction._promise(null, (_, reject) => { reject(e); }) : rejection(e); } const enterTransaction = enterTransactionScope.bind(null, this, idbMode, storeNames, parentTransaction, scopeFunc); return parentTransaction ? parentTransaction._promise(idbMode, enterTransaction, "lock") : PSD.trans ? usePSD(PSD.transless, () => this._whenReady(enterTransaction)) : this._whenReady(enterTransaction); } table(tableName) { if (!hasOwn(this._allTables, tableName)) { throw new exceptions.InvalidTable(`Table ${tableName} does not exist`); } return this._allTables[tableName]; } }; var symbolObservable = typeof Symbol !== "undefined" && "observable" in Symbol ? Symbol.observable : "@@observable"; var Observable = class { constructor(subscribe) { this._subscribe = subscribe; } subscribe(x, error, complete) { return this._subscribe(!x || typeof x === "function" ? { next: x, error, complete } : x); } [symbolObservable]() { return this; } }; function extendObservabilitySet(target, newSet) { keys(newSet).forEach((part) => { const rangeSet = target[part] || (target[part] = new RangeSet()); mergeRanges(rangeSet, newSet[part]); }); return target; } function liveQuery(querier) { let hasValue = false; let currentValue = void 0; const observable = new Observable((observer) => { const scopeFuncIsAsync = isAsyncFunction(querier); function execute(subscr) { if (scopeFuncIsAsync) { incrementExpectedAwaits(); } const exec = () => newScope(querier, { subscr, trans: null }); const rv = PSD.trans ? usePSD(PSD.transless, exec) : exec(); if (scopeFuncIsAsync) { rv.then(decrementExpectedAwaits, decrementExpectedAwaits); } return rv; } let closed = false; let accumMuts = {}; let currentObs = {}; const subscription = { get closed() { return closed; }, unsubscribe: () => { closed = true; globalEvents.storagemutated.unsubscribe(mutationListener); } }; observer.start && observer.start(subscription); let querying = false, startedListening = false; function shouldNotify() { return keys(currentObs).some((key) => accumMuts[key] && rangesOverlap(accumMuts[key], currentObs[key])); } const mutationListener = (parts) => { extendObservabilitySet(accumMuts, parts); if (shouldNotify()) { doQuery(); } }; const doQuery = () => { if (querying || closed) return; accumMuts = {}; const subscr = {}; const ret = execute(subscr); if (!startedListening) { globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener); startedListening = true; } querying = true; Promise.resolve(ret).then((result) => { hasValue = true; currentValue = result; querying = false; if (closed) return; if (shouldNotify()) { doQuery(); } else { accumMuts = {}; currentObs = subscr; observer.next && observer.next(result); } }, (err) => { querying = false; hasValue = false; observer.error && observer.error(err); subscription.unsubscribe(); }); }; doQuery(); return subscription; }); observable.hasValue = () => hasValue; observable.getValue = () => currentValue; return observable; } var domDeps; try { domDeps = { indexedDB: _global.indexedDB || _global.mozIndexedDB || _global.webkitIndexedDB || _global.msIndexedDB, IDBKeyRange: _global.IDBKeyRange || _global.webkitIDBKeyRange }; } catch (e) { domDeps = { indexedDB: null, IDBKeyRange: null }; } var Dexie = Dexie$1; props(Dexie, { ...fullNameExceptions, delete(databaseName) { const db2 = new Dexie(databaseName, { addons: [] }); return db2.delete(); }, exists(name) { return new Dexie(name, { addons: [] }).open().then((db2) => { db2.close(); return true; }).catch("NoSuchDatabaseError", () => false); }, getDatabaseNames(cb) { try { return getDatabaseNames(Dexie.dependencies).then(cb); } catch (_a) { return rejection(new exceptions.MissingAPI()); } }, defineClass() { function Class(content) { extend(this, content); } return Class; }, ignoreTransaction(scopeFunc) { return PSD.trans ? usePSD(PSD.transless, scopeFunc) : scopeFunc(); }, vip, async: function(generatorFn) { return function() { try { var rv = awaitIterator(generatorFn.apply(this, arguments)); if (!rv || typeof rv.then !== "function") return DexiePromise.resolve(rv); return rv; } catch (e) { return rejection(e); } }; }, spawn: function(generatorFn, args, thiz) { try { var rv = awaitIterator(generatorFn.apply(thiz, args || [])); if (!rv || typeof rv.then !== "function") return DexiePromise.resolve(rv); return rv; } catch (e) { return rejection(e); } }, currentTransaction: { get: () => PSD.trans || null }, waitFor: function(promiseOrFunction, optionalTimeout) { const promise = DexiePromise.resolve(typeof promiseOrFunction === "function" ? Dexie.ignoreTransaction(promiseOrFunction) : promiseOrFunction).timeout(optionalTimeout || 6e4); return PSD.trans ? PSD.trans.waitFor(promise) : promise; }, Promise: DexiePromise, debug: { get: () => debug, set: (value) => { setDebug(value, value === "dexie" ? () => true : dexieStackFrameFilter); } }, derive, extend, props, override, Events, on: globalEvents, liveQuery, extendObservabilitySet, getByKeyPath, setByKeyPath, delByKeyPath, shallowClone, deepClone, getObjectDiff, cmp, asap: asap$1, minKey, addons: [], connections, errnames, dependencies: domDeps, semVer: DEXIE_VERSION, version: DEXIE_VERSION.split(".").map((n) => parseInt(n)).reduce((p, c, i) => p + c / Math.pow(10, i * 2)) }); Dexie.maxKey = getMaxKey(Dexie.dependencies.IDBKeyRange); if (typeof dispatchEvent !== "undefined" && typeof addEventListener !== "undefined") { globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (updatedParts) => { if (!propagatingLocally) { let event; if (isIEOrEdge) { event = document.createEvent("CustomEvent"); event.initCustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, true, true, updatedParts); } else { event = new CustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, { detail: updatedParts }); } propagatingLocally = true; dispatchEvent(event); propagatingLocally = false; } }); addEventListener(STORAGE_MUTATED_DOM_EVENT_NAME, ({ detail }) => { if (!propagatingLocally) { propagateLocally(detail); } }); } function propagateLocally(updateParts) { let wasMe = propagatingLocally; try { propagatingLocally = true; globalEvents.storagemutated.fire(updateParts); } finally { propagatingLocally = wasMe; } } var propagatingLocally = false; if (typeof BroadcastChannel !== "undefined") { const bc = new BroadcastChannel(STORAGE_MUTATED_DOM_EVENT_NAME); if (typeof bc.unref === "function") { bc.unref(); } globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (changedParts) => { if (!propagatingLocally) { bc.postMessage(changedParts); } }); bc.onmessage = (ev) => { if (ev.data) propagateLocally(ev.data); }; } else if (typeof self !== "undefined" && typeof navigator !== "undefined") { globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (changedParts) => { try { if (!propagatingLocally) { if (typeof localStorage !== "undefined") { localStorage.setItem(STORAGE_MUTATED_DOM_EVENT_NAME, JSON.stringify({ trig: Math.random(), changedParts })); } if (typeof self["clients"] === "object") { [...self["clients"].matchAll({ includeUncontrolled: true })].forEach((client) => client.postMessage({ type: STORAGE_MUTATED_DOM_EVENT_NAME, changedParts })); } } } catch (_a) { } }); if (typeof addEventListener !== "undefined") { addEventListener("storage", (ev) => { if (ev.key === STORAGE_MUTATED_DOM_EVENT_NAME) { const data = JSON.parse(ev.newValue); if (data) propagateLocally(data.changedParts); } }); } const swContainer = self.document && navigator.serviceWorker; if (swContainer) { swContainer.addEventListener("message", propagateMessageLocally); } } function propagateMessageLocally({ data }) { if (data && data.type === STORAGE_MUTATED_DOM_EVENT_NAME) { propagateLocally(data.changedParts); } } DexiePromise.rejectionMapper = mapError; setDebug(debug, dexieStackFrameFilter); function shareSameDomainSuffix(hostname, vhost) { if (hostname.endsWith(vhost)) { return hostname.length === vhost.length || hostname[hostname.length - vhost.length - 1] === "."; } return false; } function extractDomainWithSuffix(hostname, publicSuffix) { const publicSuffixIndex = hostname.length - publicSuffix.length - 2; const lastDotBeforeSuffixIndex = hostname.lastIndexOf(".", publicSuffixIndex); if (lastDotBeforeSuffixIndex === -1) { return hostname; } return hostname.slice(lastDotBeforeSuffixIndex + 1); } function getDomain(suffix, hostname, options) { if (options.validHosts !== null) { const validHosts = options.validHosts; for (const vhost of validHosts) { if (shareSameDomainSuffix(hostname, vhost)) { return vhost; } } } let numberOfLeadingDots = 0; if (hostname.startsWith(".")) { while (numberOfLeadingDots < hostname.length && hostname[numberOfLeadingDots] === ".") { numberOfLeadingDots += 1; } } if (suffix.length === hostname.length - numberOfLeadingDots) { return null; } return extractDomainWithSuffix(hostname, suffix); } function getDomainWithoutSuffix(domain2, suffix) { return domain2.slice(0, -suffix.length - 1); } function extractHostname(url, urlIsValidHostname) { let start = 0; let end = url.length; let hasUpper = false; if (!urlIsValidHostname) { if (url.startsWith("data:")) { return null; } while (start < url.length && url.charCodeAt(start) <= 32) { start += 1; } while (end > start + 1 && url.charCodeAt(end - 1) <= 32) { end -= 1; } if (url.charCodeAt(start) === 47 && url.charCodeAt(start + 1) === 47) { start += 2; } else { const indexOfProtocol = url.indexOf(":/", start); if (indexOfProtocol !== -1) { const protocolSize = indexOfProtocol - start; const c0 = url.charCodeAt(start); const c1 = url.charCodeAt(start + 1); const c2 = url.charCodeAt(start + 2); const c3 = url.charCodeAt(start + 3); const c4 = url.charCodeAt(start + 4); if (protocolSize === 5 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112 && c4 === 115) { } else if (protocolSize === 4 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112) { } else if (protocolSize === 3 && c0 === 119 && c1 === 115 && c2 === 115) { } else if (protocolSize === 2 && c0 === 119 && c1 === 115) { } else { for (let i = start; i < indexOfProtocol; i += 1) { const lowerCaseCode = url.charCodeAt(i) | 32; if (!(lowerCaseCode >= 97 && lowerCaseCode <= 122 || lowerCaseCode >= 48 && lowerCaseCode <= 57 || lowerCaseCode === 46 || lowerCaseCode === 45 || lowerCaseCode === 43)) { return null; } } } start = indexOfProtocol + 2; while (url.charCodeAt(start) === 47) { start += 1; } } } let indexOfIdentifier = -1; let indexOfClosingBracket = -1; let indexOfPort = -1; for (let i = start; i < end; i += 1) { const code = url.charCodeAt(i); if (code === 35 || code === 47 || code === 63) { end = i; break; } else if (code === 64) { indexOfIdentifier = i; } else if (code === 93) { indexOfClosingBracket = i; } else if (code === 58) { indexOfPort = i; } else if (code >= 65 && code <= 90) { hasUpper = true; } } if (indexOfIdentifier !== -1 && indexOfIdentifier > start && indexOfIdentifier < end) { start = indexOfIdentifier + 1; } if (url.charCodeAt(start) === 91) { if (indexOfClosingBracket !== -1) { return url.slice(start + 1, indexOfClosingBracket).toLowerCase(); } return null; } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) { end = indexOfPort; } } while (end > start + 1 && url.charCodeAt(end - 1) === 46) { end -= 1; } const hostname = start !== 0 || end !== url.length ? url.slice(start, end) : url; if (hasUpper) { return hostname.toLowerCase(); } return hostname; } function isProbablyIpv4(hostname) { if (hostname.length < 7) { return false; } if (hostname.length > 15) { return false; } let numberOfDots = 0; for (let i = 0; i < hostname.length; i += 1) { const code = hostname.charCodeAt(i); if (code === 46) { numberOfDots += 1; } else if (code < 48 || code > 57) { return false; } } return numberOfDots === 3 && hostname.charCodeAt(0) !== 46 && hostname.charCodeAt(hostname.length - 1) !== 46; } function isProbablyIpv6(hostname) { if (hostname.length < 3) { return false; } let start = hostname.startsWith("[") ? 1 : 0; let end = hostname.length; if (hostname[end - 1] === "]") { end -= 1; } if (end - start > 39) { return false; } let hasColon = false; for (; start < end; start += 1) { const code = hostname.charCodeAt(start); if (code === 58) { hasColon = true; } else if (!(code >= 48 && code <= 57 || code >= 97 && code <= 102 || code >= 65 && code <= 90)) { return false; } } return hasColon; } function isIp(hostname) { return isProbablyIpv6(hostname) || isProbablyIpv4(hostname); } function isValidAscii(code) { return code >= 97 && code <= 122 || code >= 48 && code <= 57 || code > 127; } function is_valid_default(hostname) { if (hostname.length > 255) { return false; } if (hostname.length === 0) { return false; } if (!isValidAscii(hostname.charCodeAt(0)) && hostname.charCodeAt(0) !== 46 && hostname.charCodeAt(0) !== 95) { return false; } let lastDotIndex = -1; let lastCharCode = -1; const len = hostname.length; for (let i = 0; i < len; i += 1) { const code = hostname.charCodeAt(i); if (code === 46) { if (i - lastDotIndex > 64 || lastCharCode === 46 || lastCharCode === 45 || lastCharCode === 95) { return false; } lastDotIndex = i; } else if (!(isValidAscii(code) || code === 45 || code === 95)) { return false; } lastCharCode = code; } return len - lastDotIndex - 1 <= 63 && lastCharCode !== 45; } function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname: extractHostname2 = true, mixedInputs = true, validHosts = null, validateHostname = true }) { return { allowIcannDomains, allowPrivateDomains, detectIp, extractHostname: extractHostname2, mixedInputs, validHosts, validateHostname }; } var DEFAULT_OPTIONS = setDefaultsImpl({}); function setDefaults(options) { if (options === void 0) { return DEFAULT_OPTIONS; } return setDefaultsImpl(options); } function getSubdomain(hostname, domain2) { if (domain2.length === hostname.length) { return ""; } return hostname.slice(0, -domain2.length - 1); } function getEmptyResult() { return { domain: null, domainWithoutSuffix: null, hostname: null, isIcann: null, isIp: null, isPrivate: null, publicSuffix: null, subdomain: null }; } function resetResult(result) { result.domain = null; result.domainWithoutSuffix = null; result.hostname = null; result.isIcann = null; result.isIp = null; result.isPrivate = null; result.publicSuffix = null; result.subdomain = null; } function parseImpl(url, step, suffixLookup2, partialOptions, result) { const options = setDefaults(partialOptions); if (typeof url !== "string") { return result; } if (!options.extractHostname) { result.hostname = url; } else if (options.mixedInputs) { result.hostname = extractHostname(url, is_valid_default(url)); } else { result.hostname = extractHostname(url, false); } if (options.detectIp && result.hostname !== null) { result.isIp = isIp(result.hostname); if (result.isIp) { return result; } } if (options.validateHostname && options.extractHostname && result.hostname !== null && !is_valid_default(result.hostname)) { result.hostname = null; return result; } if (step === 0 || result.hostname === null) { return result; } suffixLookup2(result.hostname, options, result); if (step === 2 || result.publicSuffix === null) { return result; } result.domain = getDomain(result.publicSuffix, result.hostname, options); if (step === 3 || result.domain === null) { return result; } result.subdomain = getSubdomain(result.hostname, result.domain); if (step === 4) { return result; } result.domainWithoutSuffix = getDomainWithoutSuffix(result.domain, result.publicSuffix); return result; } function fast_path_default(hostname, options, out) { if (!options.allowPrivateDomains && hostname.length > 3) { const last = hostname.length - 1; const c3 = hostname.charCodeAt(last); const c2 = hostname.charCodeAt(last - 1); const c1 = hostname.charCodeAt(last - 2); const c0 = hostname.charCodeAt(last - 3); if (c3 === 109 && c2 === 111 && c1 === 99 && c0 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "com"; return true; } else if (c3 === 103 && c2 === 114 && c1 === 111 && c0 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "org"; return true; } else if (c3 === 117 && c2 === 100 && c1 === 101 && c0 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "edu"; return true; } else if (c3 === 118 && c2 === 111 && c1 === 103 && c0 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "gov"; return true; } else if (c3 === 116 && c2 === 101 && c1 === 110 && c0 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "net"; return true; } else if (c3 === 101 && c2 === 100 && c1 === 46) { out.isIcann = true; out.isPrivate = false; out.publicSuffix = "de"; return true; } } return false; } var exceptions2 = (function() { const _0 = [1, {}], _1 = [0, { "city": _0 }]; const exceptions3 = [0, { "ck": [0, { "www": _0 }], "jp": [0, { "kawasaki": _1, "kitakyushu": _1, "kobe": _1, "nagoya": _1, "sapporo": _1, "sendai": _1, "yokohama": _1 }] }]; return exceptions3; })(); var rules = (function() { const _2 = [1, {}], _3 = [2, {}], _4 = [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2 }], _5 = [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 }], _6 = [0, { "*": _3 }], _7 = [2, { "s": _6 }], _8 = [0, { "relay": _3 }], _9 = [2, { "id": _3 }], _10 = [1, { "gov": _2 }], _11 = [0, { "airflow": _6, "transfer-webapp": _3 }], _12 = [0, { "transfer-webapp": _3, "transfer-webapp-fips": _3 }], _13 = [0, { "notebook": _3, "studio": _3 }], _14 = [0, { "labeling": _3, "notebook": _3, "studio": _3 }], _15 = [0, { "notebook": _3 }], _16 = [0, { "labeling": _3, "notebook": _3, "notebook-fips": _3, "studio": _3 }], _17 = [0, { "notebook": _3, "notebook-fips": _3, "studio": _3, "studio-fips": _3 }], _18 = [0, { "*": _2 }], _19 = [1, { "co": _3 }], _20 = [0, { "objects": _3 }], _21 = [2, { "nodes": _3 }], _22 = [0, { "my": _3 }], _23 = [0, { "s3": _3, "s3-accesspoint": _3, "s3-website": _3 }], _24 = [0, { "s3": _3, "s3-accesspoint": _3 }], _25 = [0, { "direct": _3 }], _26 = [0, { "webview-assets": _3 }], _27 = [0, { "vfs": _3, "webview-assets": _3 }], _28 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3, "aws-cloud9": _26, "cloud9": _27 }], _29 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _24, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3, "aws-cloud9": _26, "cloud9": _27 }], _30 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3, "analytics-gateway": _3, "aws-cloud9": _26, "cloud9": _27 }], _31 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3 }], _32 = [0, { "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-fips": _3, "s3-website": _3 }], _33 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _32, "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-fips": _3, "s3-object-lambda": _3, "s3-website": _3, "aws-cloud9": _26, "cloud9": _27 }], _34 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _32, "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-deprecated": _3, "s3-fips": _3, "s3-object-lambda": _3, "s3-website": _3, "analytics-gateway": _3, "aws-cloud9": _26, "cloud9": _27 }], _35 = [0, { "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-fips": _3 }], _36 = [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _35, "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-fips": _3, "s3-object-lambda": _3, "s3-website": _3 }], _37 = [0, { "auth": _3 }], _38 = [0, { "auth": _3, "auth-fips": _3 }], _39 = [0, { "auth-fips": _3 }], _40 = [0, { "apps": _3 }], _41 = [0, { "paas": _3 }], _42 = [2, { "eu": _3 }], _43 = [0, { "app": _3 }], _44 = [0, { "site": _3 }], _45 = [1, { "com": _2, "edu": _2, "net": _2, "org": _2 }], _46 = [0, { "j": _3 }], _47 = [0, { "dyn": _3 }], _48 = [2, { "web": _3 }], _49 = [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2 }], _50 = [0, { "p": _3 }], _51 = [0, { "user": _3 }], _52 = [0, { "shop": _3 }], _53 = [0, { "cdn": _3 }], _54 = [2, { "raw": _6 }], _55 = [0, { "cust": _3, "reservd": _3 }], _56 = [0, { "cust": _3 }], _57 = [0, { "s3": _3 }], _58 = [1, { "biz": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2 }], _59 = [0, { "ipfs": _3 }], _60 = [1, { "framer": _3 }], _61 = [0, { "forgot": _3 }], _62 = [1, { "gs": _2 }], _63 = [0, { "nes": _2 }], _64 = [1, { "k12": _2, "cc": _2, "lib": _2 }], _65 = [1, { "cc": _2, "lib": _2 }]; const rules2 = [0, { "ac": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "drr": _3, "feedback": _3, "forms": _3 }], "ad": _2, "ae": [1, { "ac": _2, "co": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "sch": _2 }], "aero": [1, { "airline": _2, "airport": _2, "accident-investigation": _2, "accident-prevention": _2, "aerobatic": _2, "aeroclub": _2, "aerodrome": _2, "agents": _2, "air-surveillance": _2, "air-traffic-control": _2, "aircraft": _2, "airtraffic": _2, "ambulance": _2, "association": _2, "author": _2, "ballooning": _2, "broker": _2, "caa": _2, "cargo": _2, "catering": _2, "certification": _2, "championship": _2, "charter": _2, "civilaviation": _2, "club": _2, "conference": _2, "consultant": _2, "consulting": _2, "control": _2, "council": _2, "crew": _2, "design": _2, "dgca": _2, "educator": _2, "emergency": _2, "engine": _2, "engineer": _2, "entertainment": _2, "equipment": _2, "exchange": _2, "express": _2, "federation": _2, "flight": _2, "freight": _2, "fuel": _2, "gliding": _2, "government": _2, "groundhandling": _2, "group": _2, "hanggliding": _2, "homebuilt": _2, "insurance": _2, "journal": _2, "journalist": _2, "leasing": _2, "logistics": _2, "magazine": _2, "maintenance": _2, "marketplace": _2, "media": _2, "microlight": _2, "modelling": _2, "navigation": _2, "parachuting": _2, "paragliding": _2, "passenger-association": _2, "pilot": _2, "press": _2, "production": _2, "recreation": _2, "repbody": _2, "res": _2, "research": _2, "rotorcraft": _2, "safety": _2, "scientist": _2, "services": _2, "show": _2, "skydiving": _2, "software": _2, "student": _2, "taxi": _2, "trader": _2, "trading": _2, "trainer": _2, "union": _2, "workinggroup": _2, "works": _2 }], "af": _4, "ag": [1, { "co": _2, "com": _2, "net": _2, "nom": _2, "org": _2, "obj": _3 }], "ai": [1, { "com": _2, "net": _2, "off": _2, "org": _2, "uwu": _3, "framer": _3 }], "al": _5, "am": [1, { "co": _2, "com": _2, "commune": _2, "net": _2, "org": _2, "radio": _3 }], "ao": [1, { "co": _2, "ed": _2, "edu": _2, "gov": _2, "gv": _2, "it": _2, "og": _2, "org": _2, "pb": _2 }], "aq": _2, "ar": [1, { "bet": _2, "com": _2, "coop": _2, "edu": _2, "gob": _2, "gov": _2, "int": _2, "mil": _2, "musica": _2, "mutual": _2, "net": _2, "org": _2, "seg": _2, "senasa": _2, "tur": _2 }], "arpa": [1, { "e164": _2, "home": _2, "in-addr": _2, "ip6": _2, "iris": _2, "uri": _2, "urn": _2 }], "as": _10, "asia": [1, { "cloudns": _3, "daemon": _3, "dix": _3 }], "at": [1, { "4": _3, "ac": [1, { "sth": _2 }], "co": _2, "gv": _2, "or": _2, "funkfeuer": [0, { "wien": _3 }], "futurecms": [0, { "*": _3, "ex": _6, "in": _6 }], "futurehosting": _3, "futuremailing": _3, "ortsinfo": [0, { "ex": _6, "kunden": _6 }], "biz": _3, "info": _3, "123webseite": _3, "priv": _3, "my": _3, "myspreadshop": _3, "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3 }], "au": [1, { "asn": _2, "com": [1, { "cloudlets": [0, { "mel": _3 }], "myspreadshop": _3 }], "edu": [1, { "act": _2, "catholic": _2, "nsw": [1, { "schools": _2 }], "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 }], "gov": [1, { "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 }], "id": _2, "net": _2, "org": _2, "conf": _2, "oz": _2, "act": _2, "nsw": _2, "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 }], "aw": [1, { "com": _2 }], "ax": _2, "az": [1, { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pp": _2, "pro": _2 }], "ba": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "rs": _3 }], "bb": [1, { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "store": _2, "tv": _2 }], "bd": _18, "be": [1, { "ac": _2, "cloudns": _3, "webhosting": _3, "interhostsolutions": [0, { "cloud": _3 }], "kuleuven": [0, { "ezproxy": _3 }], "123website": _3, "myspreadshop": _3, "transurl": _6 }], "bf": _10, "bg": [1, { "0": _2, "1": _2, "2": _2, "3": _2, "4": _2, "5": _2, "6": _2, "7": _2, "8": _2, "9": _2, "a": _2, "b": _2, "c": _2, "d": _2, "e": _2, "f": _2, "g": _2, "h": _2, "i": _2, "j": _2, "k": _2, "l": _2, "m": _2, "n": _2, "o": _2, "p": _2, "q": _2, "r": _2, "s": _2, "t": _2, "u": _2, "v": _2, "w": _2, "x": _2, "y": _2, "z": _2, "barsy": _3 }], "bh": _4, "bi": [1, { "co": _2, "com": _2, "edu": _2, "or": _2, "org": _2 }], "biz": [1, { "activetrail": _3, "cloud-ip": _3, "cloudns": _3, "jozi": _3, "dyndns": _3, "for-better": _3, "for-more": _3, "for-some": _3, "for-the": _3, "selfip": _3, "webhop": _3, "orx": _3, "mmafan": _3, "myftp": _3, "no-ip": _3, "dscloud": _3 }], "bj": [1, { "africa": _2, "agro": _2, "architectes": _2, "assur": _2, "avocats": _2, "co": _2, "com": _2, "eco": _2, "econo": _2, "edu": _2, "info": _2, "loisirs": _2, "money": _2, "net": _2, "org": _2, "ote": _2, "restaurant": _2, "resto": _2, "tourism": _2, "univ": _2 }], "bm": _4, "bn": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "co": _3 }], "bo": [1, { "com": _2, "edu": _2, "gob": _2, "int": _2, "mil": _2, "net": _2, "org": _2, "tv": _2, "web": _2, "academia": _2, "agro": _2, "arte": _2, "blog": _2, "bolivia": _2, "ciencia": _2, "cooperativa": _2, "democracia": _2, "deporte": _2, "ecologia": _2, "economia": _2, "empresa": _2, "indigena": _2, "industria": _2, "info": _2, "medicina": _2, "movimiento": _2, "musica": _2, "natural": _2, "nombre": _2, "noticias": _2, "patria": _2, "plurinacional": _2, "politica": _2, "profesional": _2, "pueblo": _2, "revista": _2, "salud": _2, "tecnologia": _2, "tksat": _2, "transporte": _2, "wiki": _2 }], "br": [1, { "9guacu": _2, "abc": _2, "adm": _2, "adv": _2, "agr": _2, "aju": _2, "am": _2, "anani": _2, "aparecida": _2, "app": _2, "arq": _2, "art": _2, "ato": _2, "b": _2, "barueri": _2, "belem": _2, "bet": _2, "bhz": _2, "bib": _2, "bio": _2, "blog": _2, "bmd": _2, "boavista": _2, "bsb": _2, "campinagrande": _2, "campinas": _2, "caxias": _2, "cim": _2, "cng": _2, "cnt": _2, "com": [1, { "simplesite": _3 }], "contagem": _2, "coop": _2, "coz": _2, "cri": _2, "cuiaba": _2, "curitiba": _2, "def": _2, "des": _2, "det": _2, "dev": _2, "ecn": _2, "eco": _2, "edu": _2, "emp": _2, "enf": _2, "eng": _2, "esp": _2, "etc": _2, "eti": _2, "far": _2, "feira": _2, "flog": _2, "floripa": _2, "fm": _2, "fnd": _2, "fortal": _2, "fot": _2, "foz": _2, "fst": _2, "g12": _2, "geo": _2, "ggf": _2, "goiania": _2, "gov": [1, { "ac": _2, "al": _2, "am": _2, "ap": _2, "ba": _2, "ce": _2, "df": _2, "es": _2, "go": _2, "ma": _2, "mg": _2, "ms": _2, "mt": _2, "pa": _2, "pb": _2, "pe": _2, "pi": _2, "pr": _2, "rj": _2, "rn": _2, "ro": _2, "rr": _2, "rs": _2, "sc": _2, "se": _2, "sp": _2, "to": _2 }], "gru": _2, "imb": _2, "ind": _2, "inf": _2, "jab": _2, "jampa": _2, "jdf": _2, "joinville": _2, "jor": _2, "jus": _2, "leg": [1, { "ac": _3, "al": _3, "am": _3, "ap": _3, "ba": _3, "ce": _3, "df": _3, "es": _3, "go": _3, "ma": _3, "mg": _3, "ms": _3, "mt": _3, "pa": _3, "pb": _3, "pe": _3, "pi": _3, "pr": _3, "rj": _3, "rn": _3, "ro": _3, "rr": _3, "rs": _3, "sc": _3, "se": _3, "sp": _3, "to": _3 }], "leilao": _2, "lel": _2, "log": _2, "londrina": _2, "macapa": _2, "maceio": _2, "manaus": _2, "maringa": _2, "mat": _2, "med": _2, "mil": _2, "morena": _2, "mp": _2, "mus": _2, "natal": _2, "net": _2, "niteroi": _2, "nom": _18, "not": _2, "ntr": _2, "odo": _2, "ong": _2, "org": _2, "osasco": _2, "palmas": _2, "poa": _2, "ppg": _2, "pro": _2, "psc": _2, "psi": _2, "pvh": _2, "qsl": _2, "radio": _2, "rec": _2, "recife": _2, "rep": _2, "ribeirao": _2, "rio": _2, "riobranco": _2, "riopreto": _2, "salvador": _2, "sampa": _2, "santamaria": _2, "santoandre": _2, "saobernardo": _2, "saogonca": _2, "seg": _2, "sjc": _2, "slg": _2, "slz": _2, "sorocaba": _2, "srv": _2, "taxi": _2, "tc": _2, "tec": _2, "teo": _2, "the": _2, "tmp": _2, "trd": _2, "tur": _2, "tv": _2, "udi": _2, "vet": _2, "vix": _2, "vlog": _2, "wiki": _2, "zlg": _2, "tche": _3 }], "bs": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "we": _3 }], "bt": _4, "bv": _2, "bw": [1, { "ac": _2, "co": _2, "gov": _2, "net": _2, "org": _2 }], "by": [1, { "gov": _2, "mil": _2, "com": _2, "of": _2, "mediatech": _3 }], "bz": [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "za": _3, "mydns": _3, "gsj": _3 }], "ca": [1, { "ab": _2, "bc": _2, "mb": _2, "nb": _2, "nf": _2, "nl": _2, "ns": _2, "nt": _2, "nu": _2, "on": _2, "pe": _2, "qc": _2, "sk": _2, "yk": _2, "gc": _2, "barsy": _3, "awdev": _6, "co": _3, "no-ip": _3, "onid": _3, "myspreadshop": _3, "box": _3 }], "cat": _2, "cc": [1, { "cleverapps": _3, "cloudns": _3, "ftpaccess": _3, "game-server": _3, "myphotos": _3, "scrapping": _3, "twmail": _3, "csx": _3, "fantasyleague": _3, "spawn": [0, { "instances": _3 }] }], "cd": _10, "cf": _2, "cg": _2, "ch": [1, { "square7": _3, "cloudns": _3, "cloudscale": [0, { "cust": _3, "lpg": _20, "rma": _20 }], "objectstorage": [0, { "lpg": _3, "rma": _3 }], "flow": [0, { "ae": [0, { "alp1": _3 }], "appengine": _3 }], "linkyard-cloud": _3, "gotdns": _3, "dnsking": _3, "123website": _3, "myspreadshop": _3, "firenet": [0, { "*": _3, "svc": _6 }], "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3 }], "ci": [1, { "ac": _2, "xn--aroport-bya": _2, "aéroport": _2, "asso": _2, "co": _2, "com": _2, "ed": _2, "edu": _2, "go": _2, "gouv": _2, "int": _2, "net": _2, "or": _2, "org": _2 }], "ck": _18, "cl": [1, { "co": _2, "gob": _2, "gov": _2, "mil": _2, "cloudns": _3 }], "cm": [1, { "co": _2, "com": _2, "gov": _2, "net": _2 }], "cn": [1, { "ac": _2, "com": [1, { "amazonaws": [0, { "cn-north-1": [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-deprecated": _3, "s3-object-lambda": _3, "s3-website": _3 }], "cn-northwest-1": [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _24, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3 }], "compute": _6, "airflow": [0, { "cn-north-1": _6, "cn-northwest-1": _6 }], "eb": [0, { "cn-north-1": _3, "cn-northwest-1": _3 }], "elb": _6 }], "amazonwebservices": [0, { "on": [0, { "cn-north-1": _11, "cn-northwest-1": _11 }] }], "sagemaker": [0, { "cn-north-1": _13, "cn-northwest-1": _13 }] }], "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "xn--55qx5d": _2, "公司": _2, "xn--od0alg": _2, "網絡": _2, "xn--io0a7i": _2, "网络": _2, "ah": _2, "bj": _2, "cq": _2, "fj": _2, "gd": _2, "gs": _2, "gx": _2, "gz": _2, "ha": _2, "hb": _2, "he": _2, "hi": _2, "hk": _2, "hl": _2, "hn": _2, "jl": _2, "js": _2, "jx": _2, "ln": _2, "mo": _2, "nm": _2, "nx": _2, "qh": _2, "sc": _2, "sd": _2, "sh": [1, { "as": _3 }], "sn": _2, "sx": _2, "tj": _2, "tw": _2, "xj": _2, "xz": _2, "yn": _2, "zj": _2, "canva-apps": _3, "canvasite": _22, "myqnapcloud": _3, "quickconnect": _25 }], "co": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "carrd": _3, "crd": _3, "otap": _6, "hidns": _3, "leadpages": _3, "lpages": _3, "mypi": _3, "xmit": _6, "firewalledreplit": _9, "repl": _9, "supabase": _3 }], "com": [1, { "a2hosted": _3, "cpserver": _3, "adobeaemcloud": [2, { "dev": _6 }], "africa": _3, "airkitapps": _3, "airkitapps-au": _3, "aivencloud": _3, "alibabacloudcs": _3, "kasserver": _3, "amazonaws": [0, { "af-south-1": _28, "ap-east-1": _29, "ap-northeast-1": _30, "ap-northeast-2": _30, "ap-northeast-3": _28, "ap-south-1": _30, "ap-south-2": _31, "ap-southeast-1": _30, "ap-southeast-2": _30, "ap-southeast-3": _31, "ap-southeast-4": _31, "ap-southeast-5": [0, { "execute-api": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-deprecated": _3, "s3-object-lambda": _3, "s3-website": _3 }], "ca-central-1": _33, "ca-west-1": [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _32, "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-fips": _3, "s3-object-lambda": _3, "s3-website": _3 }], "eu-central-1": _30, "eu-central-2": _31, "eu-north-1": _29, "eu-south-1": _28, "eu-south-2": _31, "eu-west-1": [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-deprecated": _3, "s3-object-lambda": _3, "s3-website": _3, "analytics-gateway": _3, "aws-cloud9": _26, "cloud9": _27 }], "eu-west-2": _29, "eu-west-3": _28, "il-central-1": [0, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _23, "s3": _3, "s3-accesspoint": _3, "s3-object-lambda": _3, "s3-website": _3, "aws-cloud9": _26, "cloud9": [0, { "vfs": _3 }] }], "me-central-1": _31, "me-south-1": _29, "sa-east-1": _28, "us-east-1": [2, { "execute-api": _3, "emrappui-prod": _3, "emrnotebooks-prod": _3, "emrstudio-prod": _3, "dualstack": _32, "s3": _3, "s3-accesspoint": _3, "s3-accesspoint-fips": _3, "s3-deprecated": _3, "s3-fips": _3, "s3-object-lambda": _3, "s3-website": _3, "analytics-gateway": _3, "aws-cloud9": _26, "cloud9": _27 }], "us-east-2": _34, "us-gov-east-1": _36, "us-gov-west-1": _36, "us-west-1": _33, "us-west-2": _34, "compute": _6, "compute-1": _6, "airflow": [0, { "af-south-1": _6, "ap-east-1": _6, "ap-northeast-1": _6, "ap-northeast-2": _6, "ap-northeast-3": _6, "ap-south-1": _6, "ap-south-2": _6, "ap-southeast-1": _6, "ap-southeast-2": _6, "ap-southeast-3": _6, "ap-southeast-4": _6, "ap-southeast-5": _6, "ca-central-1": _6, "ca-west-1": _6, "eu-central-1": _6, "eu-central-2": _6, "eu-north-1": _6, "eu-south-1": _6, "eu-south-2": _6, "eu-west-1": _6, "eu-west-2": _6, "eu-west-3": _6, "il-central-1": _6, "me-central-1": _6, "me-south-1": _6, "sa-east-1": _6, "us-east-1": _6, "us-east-2": _6, "us-west-1": _6, "us-west-2": _6 }], "s3": _3, "s3-1": _3, "s3-ap-east-1": _3, "s3-ap-northeast-1": _3, "s3-ap-northeast-2": _3, "s3-ap-northeast-3": _3, "s3-ap-south-1": _3, "s3-ap-southeast-1": _3, "s3-ap-southeast-2": _3, "s3-ca-central-1": _3, "s3-eu-central-1": _3, "s3-eu-north-1": _3, "s3-eu-west-1": _3, "s3-eu-west-2": _3, "s3-eu-west-3": _3, "s3-external-1": _3, "s3-fips-us-gov-east-1": _3, "s3-fips-us-gov-west-1": _3, "s3-global": [0, { "accesspoint": [0, { "mrap": _3 }] }], "s3-me-south-1": _3, "s3-sa-east-1": _3, "s3-us-east-2": _3, "s3-us-gov-east-1": _3, "s3-us-gov-west-1": _3, "s3-us-west-1": _3, "s3-us-west-2": _3, "s3-website-ap-northeast-1": _3, "s3-website-ap-southeast-1": _3, "s3-website-ap-southeast-2": _3, "s3-website-eu-west-1": _3, "s3-website-sa-east-1": _3, "s3-website-us-east-1": _3, "s3-website-us-gov-west-1": _3, "s3-website-us-west-1": _3, "s3-website-us-west-2": _3, "elb": _6 }], "amazoncognito": [0, { "af-south-1": _37, "ap-east-1": _37, "ap-northeast-1": _37, "ap-northeast-2": _37, "ap-northeast-3": _37, "ap-south-1": _37, "ap-south-2": _37, "ap-southeast-1": _37, "ap-southeast-2": _37, "ap-southeast-3": _37, "ap-southeast-4": _37, "ap-southeast-5": _37, "ap-southeast-7": _37, "ca-central-1": _37, "ca-west-1": _37, "eu-central-1": _37, "eu-central-2": _37, "eu-north-1": _37, "eu-south-1": _37, "eu-south-2": _37, "eu-west-1": _37, "eu-west-2": _37, "eu-west-3": _37, "il-central-1": _37, "me-central-1": _37, "me-south-1": _37, "mx-central-1": _37, "sa-east-1": _37, "us-east-1": _38, "us-east-2": _38, "us-gov-east-1": _39, "us-gov-west-1": _39, "us-west-1": _38, "us-west-2": _38 }], "amplifyapp": _3, "awsapprunner": _6, "awsapps": _3, "elasticbeanstalk": [2, { "af-south-1": _3, "ap-east-1": _3, "ap-northeast-1": _3, "ap-northeast-2": _3, "ap-northeast-3": _3, "ap-south-1": _3, "ap-southeast-1": _3, "ap-southeast-2": _3, "ap-southeast-3": _3, "ca-central-1": _3, "eu-central-1": _3, "eu-north-1": _3, "eu-south-1": _3, "eu-west-1": _3, "eu-west-2": _3, "eu-west-3": _3, "il-central-1": _3, "me-south-1": _3, "sa-east-1": _3, "us-east-1": _3, "us-east-2": _3, "us-gov-east-1": _3, "us-gov-west-1": _3, "us-west-1": _3, "us-west-2": _3 }], "awsglobalaccelerator": _3, "siiites": _3, "appspacehosted": _3, "appspaceusercontent": _3, "on-aptible": _3, "myasustor": _3, "balena-devices": _3, "boutir": _3, "bplaced": _3, "cafjs": _3, "canva-apps": _3, "cdn77-storage": _3, "br": _3, "cn": _3, "de": _3, "eu": _3, "jpn": _3, "mex": _3, "ru": _3, "sa": _3, "uk": _3, "us": _3, "za": _3, "clever-cloud": [0, { "services": _6 }], "dnsabr": _3, "ip-ddns": _3, "jdevcloud": _3, "wpdevcloud": _3, "cf-ipfs": _3, "cloudflare-ipfs": _3, "trycloudflare": _3, "co": _3, "devinapps": _6, "builtwithdark": _3, "datadetect": [0, { "demo": _3, "instance": _3 }], "dattolocal": _3, "dattorelay": _3, "dattoweb": _3, "mydatto": _3, "digitaloceanspaces": _6, "discordsays": _3, "discordsez": _3, "drayddns": _3, "dreamhosters": _3, "durumis": _3, "mydrobo": _3, "blogdns": _3, "cechire": _3, "dnsalias": _3, "dnsdojo": _3, "doesntexist": _3, "dontexist": _3, "doomdns": _3, "dyn-o-saur": _3, "dynalias": _3, "dyndns-at-home": _3, "dyndns-at-work": _3, "dyndns-blog": _3, "dyndns-free": _3, "dyndns-home": _3, "dyndns-ip": _3, "dyndns-mail": _3, "dyndns-office": _3, "dyndns-pics": _3, "dyndns-remote": _3, "dyndns-server": _3, "dyndns-web": _3, "dyndns-wiki": _3, "dyndns-work": _3, "est-a-la-maison": _3, "est-a-la-masion": _3, "est-le-patron": _3, "est-mon-blogueur": _3, "from-ak": _3, "from-al": _3, "from-ar": _3, "from-ca": _3, "from-ct": _3, "from-dc": _3, "from-de": _3, "from-fl": _3, "from-ga": _3, "from-hi": _3, "from-ia": _3, "from-id": _3, "from-il": _3, "from-in": _3, "from-ks": _3, "from-ky": _3, "from-ma": _3, "from-md": _3, "from-mi": _3, "from-mn": _3, "from-mo": _3, "from-ms": _3, "from-mt": _3, "from-nc": _3, "from-nd": _3, "from-ne": _3, "from-nh": _3, "from-nj": _3, "from-nm": _3, "from-nv": _3, "from-oh": _3, "from-ok": _3, "from-or": _3, "from-pa": _3, "from-pr": _3, "from-ri": _3, "from-sc": _3, "from-sd": _3, "from-tn": _3, "from-tx": _3, "from-ut": _3, "from-va": _3, "from-vt": _3, "from-wa": _3, "from-wi": _3, "from-wv": _3, "from-wy": _3, "getmyip": _3, "gotdns": _3, "hobby-site": _3, "homelinux": _3, "homeunix": _3, "iamallama": _3, "is-a-anarchist": _3, "is-a-blogger": _3, "is-a-bookkeeper": _3, "is-a-bulls-fan": _3, "is-a-caterer": _3, "is-a-chef": _3, "is-a-conservative": _3, "is-a-cpa": _3, "is-a-cubicle-slave": _3, "is-a-democrat": _3, "is-a-designer": _3, "is-a-doctor": _3, "is-a-financialadvisor": _3, "is-a-geek": _3, "is-a-green": _3, "is-a-guru": _3, "is-a-hard-worker": _3, "is-a-hunter": _3, "is-a-landscaper": _3, "is-a-lawyer": _3, "is-a-liberal": _3, "is-a-libertarian": _3, "is-a-llama": _3, "is-a-musician": _3, "is-a-nascarfan": _3, "is-a-nurse": _3, "is-a-painter": _3, "is-a-personaltrainer": _3, "is-a-photographer": _3, "is-a-player": _3, "is-a-republican": _3, "is-a-rockstar": _3, "is-a-socialist": _3, "is-a-student": _3, "is-a-teacher": _3, "is-a-techie": _3, "is-a-therapist": _3, "is-an-accountant": _3, "is-an-actor": _3, "is-an-actress": _3, "is-an-anarchist": _3, "is-an-artist": _3, "is-an-engineer": _3, "is-an-entertainer": _3, "is-certified": _3, "is-gone": _3, "is-into-anime": _3, "is-into-cars": _3, "is-into-cartoons": _3, "is-into-games": _3, "is-leet": _3, "is-not-certified": _3, "is-slick": _3, "is-uberleet": _3, "is-with-theband": _3, "isa-geek": _3, "isa-hockeynut": _3, "issmarterthanyou": _3, "likes-pie": _3, "likescandy": _3, "neat-url": _3, "saves-the-whales": _3, "selfip": _3, "sells-for-less": _3, "sells-for-u": _3, "servebbs": _3, "simple-url": _3, "space-to-rent": _3, "teaches-yoga": _3, "writesthisblog": _3, "ddnsfree": _3, "ddnsgeek": _3, "giize": _3, "gleeze": _3, "kozow": _3, "loseyourip": _3, "ooguy": _3, "theworkpc": _3, "mytuleap": _3, "tuleap-partners": _3, "encoreapi": _3, "evennode": [0, { "eu-1": _3, "eu-2": _3, "eu-3": _3, "eu-4": _3, "us-1": _3, "us-2": _3, "us-3": _3, "us-4": _3 }], "onfabrica": _3, "fastly-edge": _3, "fastly-terrarium": _3, "fastvps-server": _3, "mydobiss": _3, "firebaseapp": _3, "fldrv": _3, "forgeblocks": _3, "framercanvas": _3, "freebox-os": _3, "freeboxos": _3, "freemyip": _3, "aliases121": _3, "gentapps": _3, "gentlentapis": _3, "githubusercontent": _3, "0emm": _6, "appspot": [2, { "r": _6 }], "blogspot": _3, "codespot": _3, "googleapis": _3, "googlecode": _3, "pagespeedmobilizer": _3, "withgoogle": _3, "withyoutube": _3, "grayjayleagues": _3, "hatenablog": _3, "hatenadiary": _3, "herokuapp": _3, "gr": _3, "smushcdn": _3, "wphostedmail": _3, "wpmucdn": _3, "pixolino": _3, "apps-1and1": _3, "live-website": _3, "webspace-host": _3, "dopaas": _3, "hosted-by-previder": _41, "hosteur": [0, { "rag-cloud": _3, "rag-cloud-ch": _3 }], "ik-server": [0, { "jcloud": _3, "jcloud-ver-jpc": _3 }], "jelastic": [0, { "demo": _3 }], "massivegrid": _41, "wafaicloud": [0, { "jed": _3, "ryd": _3 }], "webadorsite": _3, "joyent": [0, { "cns": _6 }], "on-forge": _3, "on-vapor": _3, "lpusercontent": _3, "linode": [0, { "members": _3, "nodebalancer": _6 }], "linodeobjects": _6, "linodeusercontent": [0, { "ip": _3 }], "localtonet": _3, "lovableproject": _3, "barsycenter": _3, "barsyonline": _3, "lutrausercontent": _6, "modelscape": _3, "mwcloudnonprod": _3, "polyspace": _3, "mazeplay": _3, "miniserver": _3, "atmeta": _3, "fbsbx": _40, "meteorapp": _42, "routingthecloud": _3, "same-app": _3, "same-preview": _3, "mydbserver": _3, "hostedpi": _3, "mythic-beasts": [0, { "caracal": _3, "customer": _3, "fentiger": _3, "lynx": _3, "ocelot": _3, "oncilla": _3, "onza": _3, "sphinx": _3, "vs": _3, "x": _3, "yali": _3 }], "nospamproxy": [0, { "cloud": [2, { "o365": _3 }] }], "4u": _3, "nfshost": _3, "3utilities": _3, "blogsyte": _3, "ciscofreak": _3, "damnserver": _3, "ddnsking": _3, "ditchyourip": _3, "dnsiskinky": _3, "dynns": _3, "geekgalaxy": _3, "health-carereform": _3, "homesecuritymac": _3, "homesecuritypc": _3, "myactivedirectory": _3, "mysecuritycamera": _3, "myvnc": _3, "net-freaks": _3, "onthewifi": _3, "point2this": _3, "quicksytes": _3, "securitytactics": _3, "servebeer": _3, "servecounterstrike": _3, "serveexchange": _3, "serveftp": _3, "servegame": _3, "servehalflife": _3, "servehttp": _3, "servehumour": _3, "serveirc": _3, "servemp3": _3, "servep2p": _3, "servepics": _3, "servequake": _3, "servesarcasm": _3, "stufftoread": _3, "unusualperson": _3, "workisboring": _3, "myiphost": _3, "observableusercontent": [0, { "static": _3 }], "simplesite": _3, "oaiusercontent": _6, "orsites": _3, "operaunite": _3, "customer-oci": [0, { "*": _3, "oci": _6, "ocp": _6, "ocs": _6 }], "oraclecloudapps": _6, "oraclegovcloudapps": _6, "authgear-staging": _3, "authgearapps": _3, "skygearapp": _3, "outsystemscloud": _3, "ownprovider": _3, "pgfog": _3, "pagexl": _3, "gotpantheon": _3, "paywhirl": _6, "upsunapp": _3, "postman-echo": _3, "prgmr": [0, { "xen": _3 }], "project-study": [0, { "dev": _3 }], "pythonanywhere": _42, "qa2": _3, "alpha-myqnapcloud": _3, "dev-myqnapcloud": _3, "mycloudnas": _3, "mynascloud": _3, "myqnapcloud": _3, "qualifioapp": _3, "ladesk": _3, "qualyhqpartner": _6, "qualyhqportal": _6, "qbuser": _3, "quipelements": _6, "rackmaze": _3, "readthedocs-hosted": _3, "rhcloud": _3, "onrender": _3, "render": _43, "subsc-pay": _3, "180r": _3, "dojin": _3, "sakuratan": _3, "sakuraweb": _3, "x0": _3, "code": [0, { "builder": _6, "dev-builder": _6, "stg-builder": _6 }], "salesforce": [0, { "platform": [0, { "code-builder-stg": [0, { "test": [0, { "001": _6 }] }] }] }], "logoip": _3, "scrysec": _3, "firewall-gateway": _3, "myshopblocks": _3, "myshopify": _3, "shopitsite": _3, "1kapp": _3, "appchizi": _3, "applinzi": _3, "sinaapp": _3, "vipsinaapp": _3, "streamlitapp": _3, "try-snowplow": _3, "playstation-cloud": _3, "myspreadshop": _3, "w-corp-staticblitz": _3, "w-credentialless-staticblitz": _3, "w-staticblitz": _3, "stackhero-network": _3, "stdlib": [0, { "api": _3 }], "strapiapp": [2, { "media": _3 }], "streak-link": _3, "streaklinks": _3, "streakusercontent": _3, "temp-dns": _3, "dsmynas": _3, "familyds": _3, "mytabit": _3, "taveusercontent": _3, "tb-hosting": _44, "reservd": _3, "thingdustdata": _3, "townnews-staging": _3, "typeform": [0, { "pro": _3 }], "hk": _3, "it": _3, "deus-canvas": _3, "vultrobjects": _6, "wafflecell": _3, "hotelwithflight": _3, "reserve-online": _3, "cprapid": _3, "pleskns": _3, "remotewd": _3, "wiardweb": [0, { "pages": _3 }], "wixsite": _3, "wixstudio": _3, "messwithdns": _3, "woltlab-demo": _3, "wpenginepowered": [2, { "js": _3 }], "xnbay": [2, { "u2": _3, "u2-local": _3 }], "yolasite": _3 }], "coop": _2, "cr": [1, { "ac": _2, "co": _2, "ed": _2, "fi": _2, "go": _2, "or": _2, "sa": _2 }], "cu": [1, { "com": _2, "edu": _2, "gob": _2, "inf": _2, "nat": _2, "net": _2, "org": _2 }], "cv": [1, { "com": _2, "edu": _2, "id": _2, "int": _2, "net": _2, "nome": _2, "org": _2, "publ": _2 }], "cw": _45, "cx": [1, { "gov": _2, "cloudns": _3, "ath": _3, "info": _3, "assessments": _3, "calculators": _3, "funnels": _3, "paynow": _3, "quizzes": _3, "researched": _3, "tests": _3 }], "cy": [1, { "ac": _2, "biz": _2, "com": [1, { "scaleforce": _46 }], "ekloges": _2, "gov": _2, "ltd": _2, "mil": _2, "net": _2, "org": _2, "press": _2, "pro": _2, "tm": _2 }], "cz": [1, { "gov": _2, "contentproxy9": [0, { "rsc": _3 }], "realm": _3, "e4": _3, "co": _3, "metacentrum": [0, { "cloud": _6, "custom": _3 }], "muni": [0, { "cloud": [0, { "flt": _3, "usr": _3 }] }] }], "de": [1, { "bplaced": _3, "square7": _3, "com": _3, "cosidns": _47, "dnsupdater": _3, "dynamisches-dns": _3, "internet-dns": _3, "l-o-g-i-n": _3, "ddnss": [2, { "dyn": _3, "dyndns": _3 }], "dyn-ip24": _3, "dyndns1": _3, "home-webserver": [2, { "dyn": _3 }], "myhome-server": _3, "dnshome": _3, "fuettertdasnetz": _3, "isteingeek": _3, "istmein": _3, "lebtimnetz": _3, "leitungsen": _3, "traeumtgerade": _3, "frusky": _6, "goip": _3, "xn--gnstigbestellen-zvb": _3, "günstigbestellen": _3, "xn--gnstigliefern-wob": _3, "günstigliefern": _3, "hs-heilbronn": [0, { "it": [0, { "pages": _3, "pages-research": _3 }] }], "dyn-berlin": _3, "in-berlin": _3, "in-brb": _3, "in-butter": _3, "in-dsl": _3, "in-vpn": _3, "iservschule": _3, "mein-iserv": _3, "schuldock": _3, "schulplattform": _3, "schulserver": _3, "test-iserv": _3, "keymachine": _3, "co": _3, "git-repos": _3, "lcube-server": _3, "svn-repos": _3, "barsy": _3, "webspaceconfig": _3, "123webseite": _3, "rub": _3, "ruhr-uni-bochum": [2, { "noc": [0, { "io": _3 }] }], "logoip": _3, "firewall-gateway": _3, "my-gateway": _3, "my-router": _3, "spdns": _3, "my": _3, "speedpartner": [0, { "customer": _3 }], "myspreadshop": _3, "taifun-dns": _3, "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3, "dd-dns": _3, "dray-dns": _3, "draydns": _3, "dyn-vpn": _3, "dynvpn": _3, "mein-vigor": _3, "my-vigor": _3, "my-wan": _3, "syno-ds": _3, "synology-diskstation": _3, "synology-ds": _3, "virtual-user": _3, "virtualuser": _3, "community-pro": _3, "diskussionsbereich": _3 }], "dj": _2, "dk": [1, { "biz": _3, "co": _3, "firm": _3, "reg": _3, "store": _3, "123hjemmeside": _3, "myspreadshop": _3 }], "dm": _49, "do": [1, { "art": _2, "com": _2, "edu": _2, "gob": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "sld": _2, "web": _2 }], "dz": [1, { "art": _2, "asso": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "pol": _2, "soc": _2, "tm": _2 }], "ec": [1, { "abg": _2, "adm": _2, "agron": _2, "arqt": _2, "art": _2, "bar": _2, "chef": _2, "com": _2, "cont": _2, "cpa": _2, "cue": _2, "dent": _2, "dgn": _2, "disco": _2, "doc": _2, "edu": _2, "eng": _2, "esm": _2, "fin": _2, "fot": _2, "gal": _2, "gob": _2, "gov": _2, "gye": _2, "ibr": _2, "info": _2, "k12": _2, "lat": _2, "loj": _2, "med": _2, "mil": _2, "mktg": _2, "mon": _2, "net": _2, "ntr": _2, "odont": _2, "org": _2, "pro": _2, "prof": _2, "psic": _2, "psiq": _2, "pub": _2, "rio": _2, "rrpp": _2, "sal": _2, "tech": _2, "tul": _2, "tur": _2, "uio": _2, "vet": _2, "xxx": _2, "base": _3, "official": _3 }], "edu": [1, { "rit": [0, { "git-pages": _3 }] }], "ee": [1, { "aip": _2, "com": _2, "edu": _2, "fie": _2, "gov": _2, "lib": _2, "med": _2, "org": _2, "pri": _2, "riik": _2 }], "eg": [1, { "ac": _2, "com": _2, "edu": _2, "eun": _2, "gov": _2, "info": _2, "me": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sci": _2, "sport": _2, "tv": _2 }], "er": _18, "es": [1, { "com": _2, "edu": _2, "gob": _2, "nom": _2, "org": _2, "123miweb": _3, "myspreadshop": _3 }], "et": [1, { "biz": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "name": _2, "net": _2, "org": _2 }], "eu": [1, { "airkitapps": _3, "cloudns": _3, "dogado": [0, { "jelastic": _3 }], "barsy": _3, "spdns": _3, "nxa": _6, "transurl": _6, "diskstation": _3 }], "fi": [1, { "aland": _2, "dy": _3, "xn--hkkinen-5wa": _3, "häkkinen": _3, "iki": _3, "cloudplatform": [0, { "fi": _3 }], "datacenter": [0, { "demo": _3, "paas": _3 }], "kapsi": _3, "123kotisivu": _3, "myspreadshop": _3 }], "fj": [1, { "ac": _2, "biz": _2, "com": _2, "gov": _2, "info": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pro": _2 }], "fk": _18, "fm": [1, { "com": _2, "edu": _2, "net": _2, "org": _2, "radio": _3, "user": _6 }], "fo": _2, "fr": [1, { "asso": _2, "com": _2, "gouv": _2, "nom": _2, "prd": _2, "tm": _2, "avoues": _2, "cci": _2, "greta": _2, "huissier-justice": _2, "en-root": _3, "fbx-os": _3, "fbxos": _3, "freebox-os": _3, "freeboxos": _3, "goupile": _3, "123siteweb": _3, "on-web": _3, "chirurgiens-dentistes-en-france": _3, "dedibox": _3, "aeroport": _3, "avocat": _3, "chambagri": _3, "chirurgiens-dentistes": _3, "experts-comptables": _3, "medecin": _3, "notaires": _3, "pharmacien": _3, "port": _3, "veterinaire": _3, "myspreadshop": _3, "ynh": _3 }], "ga": _2, "gb": _2, "gd": [1, { "edu": _2, "gov": _2 }], "ge": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "pvt": _2, "school": _2 }], "gf": _2, "gg": [1, { "co": _2, "net": _2, "org": _2, "botdash": _3, "kaas": _3, "stackit": _3, "panel": [2, { "daemon": _3 }] }], "gh": [1, { "biz": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 }], "gi": [1, { "com": _2, "edu": _2, "gov": _2, "ltd": _2, "mod": _2, "org": _2 }], "gl": [1, { "co": _2, "com": _2, "edu": _2, "net": _2, "org": _2 }], "gm": _2, "gn": [1, { "ac": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2 }], "gov": _2, "gp": [1, { "asso": _2, "com": _2, "edu": _2, "mobi": _2, "net": _2, "org": _2 }], "gq": _2, "gr": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "barsy": _3, "simplesite": _3 }], "gs": _2, "gt": [1, { "com": _2, "edu": _2, "gob": _2, "ind": _2, "mil": _2, "net": _2, "org": _2 }], "gu": [1, { "com": _2, "edu": _2, "gov": _2, "guam": _2, "info": _2, "net": _2, "org": _2, "web": _2 }], "gw": [1, { "nx": _3 }], "gy": _49, "hk": [1, { "com": _2, "edu": _2, "gov": _2, "idv": _2, "net": _2, "org": _2, "xn--ciqpn": _2, "个人": _2, "xn--gmqw5a": _2, "個人": _2, "xn--55qx5d": _2, "公司": _2, "xn--mxtq1m": _2, "政府": _2, "xn--lcvr32d": _2, "敎育": _2, "xn--wcvs22d": _2, "教育": _2, "xn--gmq050i": _2, "箇人": _2, "xn--uc0atv": _2, "組織": _2, "xn--uc0ay4a": _2, "組织": _2, "xn--od0alg": _2, "網絡": _2, "xn--zf0avx": _2, "網络": _2, "xn--mk0axi": _2, "组織": _2, "xn--tn0ag": _2, "组织": _2, "xn--od0aq3b": _2, "网絡": _2, "xn--io0a7i": _2, "网络": _2, "inc": _3, "ltd": _3 }], "hm": _2, "hn": [1, { "com": _2, "edu": _2, "gob": _2, "mil": _2, "net": _2, "org": _2 }], "hr": [1, { "com": _2, "from": _2, "iz": _2, "name": _2, "brendly": _52 }], "ht": [1, { "adult": _2, "art": _2, "asso": _2, "com": _2, "coop": _2, "edu": _2, "firm": _2, "gouv": _2, "info": _2, "med": _2, "net": _2, "org": _2, "perso": _2, "pol": _2, "pro": _2, "rel": _2, "shop": _2, "rt": _3 }], "hu": [1, { "2000": _2, "agrar": _2, "bolt": _2, "casino": _2, "city": _2, "co": _2, "erotica": _2, "erotika": _2, "film": _2, "forum": _2, "games": _2, "hotel": _2, "info": _2, "ingatlan": _2, "jogasz": _2, "konyvelo": _2, "lakas": _2, "media": _2, "news": _2, "org": _2, "priv": _2, "reklam": _2, "sex": _2, "shop": _2, "sport": _2, "suli": _2, "szex": _2, "tm": _2, "tozsde": _2, "utazas": _2, "video": _2 }], "id": [1, { "ac": _2, "biz": _2, "co": _2, "desa": _2, "go": _2, "kop": _2, "mil": _2, "my": _2, "net": _2, "or": _2, "ponpes": _2, "sch": _2, "web": _2, "zone": _3 }], "ie": [1, { "gov": _2, "myspreadshop": _3 }], "il": [1, { "ac": _2, "co": [1, { "ravpage": _3, "mytabit": _3, "tabitorder": _3 }], "gov": _2, "idf": _2, "k12": _2, "muni": _2, "net": _2, "org": _2 }], "xn--4dbrk0ce": [1, { "xn--4dbgdty6c": _2, "xn--5dbhl8d": _2, "xn--8dbq2a": _2, "xn--hebda8b": _2 }], "ישראל": [1, { "אקדמיה": _2, "ישוב": _2, "צהל": _2, "ממשל": _2 }], "im": [1, { "ac": _2, "co": [1, { "ltd": _2, "plc": _2 }], "com": _2, "net": _2, "org": _2, "tt": _2, "tv": _2 }], "in": [1, { "5g": _2, "6g": _2, "ac": _2, "ai": _2, "am": _2, "bihar": _2, "biz": _2, "business": _2, "ca": _2, "cn": _2, "co": _2, "com": _2, "coop": _2, "cs": _2, "delhi": _2, "dr": _2, "edu": _2, "er": _2, "firm": _2, "gen": _2, "gov": _2, "gujarat": _2, "ind": _2, "info": _2, "int": _2, "internet": _2, "io": _2, "me": _2, "mil": _2, "net": _2, "nic": _2, "org": _2, "pg": _2, "post": _2, "pro": _2, "res": _2, "travel": _2, "tv": _2, "uk": _2, "up": _2, "us": _2, "cloudns": _3, "barsy": _3, "web": _3, "supabase": _3 }], "info": [1, { "cloudns": _3, "dynamic-dns": _3, "barrel-of-knowledge": _3, "barrell-of-knowledge": _3, "dyndns": _3, "for-our": _3, "groks-the": _3, "groks-this": _3, "here-for-more": _3, "knowsitall": _3, "selfip": _3, "webhop": _3, "barsy": _3, "mayfirst": _3, "mittwald": _3, "mittwaldserver": _3, "typo3server": _3, "dvrcam": _3, "ilovecollege": _3, "no-ip": _3, "forumz": _3, "nsupdate": _3, "dnsupdate": _3, "v-info": _3 }], "int": [1, { "eu": _2 }], "io": [1, { "2038": _3, "co": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "on-acorn": _6, "myaddr": _3, "apigee": _3, "b-data": _3, "beagleboard": _3, "bitbucket": _3, "bluebite": _3, "boxfuse": _3, "brave": _7, "browsersafetymark": _3, "bubble": _53, "bubbleapps": _3, "bigv": [0, { "uk0": _3 }], "cleverapps": _3, "cloudbeesusercontent": _3, "dappnode": [0, { "dyndns": _3 }], "darklang": _3, "definima": _3, "dedyn": _3, "icp0": _54, "icp1": _54, "qzz": _3, "fh-muenster": _3, "shw": _3, "forgerock": [0, { "id": _3 }], "github": _3, "gitlab": _3, "lolipop": _3, "hasura-app": _3, "hostyhosting": _3, "hypernode": _3, "moonscale": _6, "beebyte": _41, "beebyteapp": [0, { "sekd1": _3 }], "jele": _3, "webthings": _3, "loginline": _3, "barsy": _3, "azurecontainer": _6, "ngrok": [2, { "ap": _3, "au": _3, "eu": _3, "in": _3, "jp": _3, "sa": _3, "us": _3 }], "nodeart": [0, { "stage": _3 }], "pantheonsite": _3, "pstmn": [2, { "mock": _3 }], "protonet": _3, "qcx": [2, { "sys": _6 }], "qoto": _3, "vaporcloud": _3, "myrdbx": _3, "rb-hosting": _44, "on-k3s": _6, "on-rio": _6, "readthedocs": _3, "resindevice": _3, "resinstaging": [0, { "devices": _3 }], "hzc": _3, "sandcats": _3, "scrypted": [0, { "client": _3 }], "mo-siemens": _3, "lair": _40, "stolos": _6, "musician": _3, "utwente": _3, "edugit": _3, "telebit": _3, "thingdust": [0, { "dev": _55, "disrec": _55, "prod": _56, "testing": _55 }], "tickets": _3, "webflow": _3, "webflowtest": _3, "editorx": _3, "wixstudio": _3, "basicserver": _3, "virtualserver": _3 }], "iq": _5, "ir": [1, { "ac": _2, "co": _2, "gov": _2, "id": _2, "net": _2, "org": _2, "sch": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2, "arvanedge": _3, "vistablog": _3 }], "is": _2, "it": [1, { "edu": _2, "gov": _2, "abr": _2, "abruzzo": _2, "aosta-valley": _2, "aostavalley": _2, "bas": _2, "basilicata": _2, "cal": _2, "calabria": _2, "cam": _2, "campania": _2, "emilia-romagna": _2, "emiliaromagna": _2, "emr": _2, "friuli-v-giulia": _2, "friuli-ve-giulia": _2, "friuli-vegiulia": _2, "friuli-venezia-giulia": _2, "friuli-veneziagiulia": _2, "friuli-vgiulia": _2, "friuliv-giulia": _2, "friulive-giulia": _2, "friulivegiulia": _2, "friulivenezia-giulia": _2, "friuliveneziagiulia": _2, "friulivgiulia": _2, "fvg": _2, "laz": _2, "lazio": _2, "lig": _2, "liguria": _2, "lom": _2, "lombardia": _2, "lombardy": _2, "lucania": _2, "mar": _2, "marche": _2, "mol": _2, "molise": _2, "piedmont": _2, "piemonte": _2, "pmn": _2, "pug": _2, "puglia": _2, "sar": _2, "sardegna": _2, "sardinia": _2, "sic": _2, "sicilia": _2, "sicily": _2, "taa": _2, "tos": _2, "toscana": _2, "trentin-sud-tirol": _2, "xn--trentin-sd-tirol-rzb": _2, "trentin-süd-tirol": _2, "trentin-sudtirol": _2, "xn--trentin-sdtirol-7vb": _2, "trentin-südtirol": _2, "trentin-sued-tirol": _2, "trentin-suedtirol": _2, "trentino": _2, "trentino-a-adige": _2, "trentino-aadige": _2, "trentino-alto-adige": _2, "trentino-altoadige": _2, "trentino-s-tirol": _2, "trentino-stirol": _2, "trentino-sud-tirol": _2, "xn--trentino-sd-tirol-c3b": _2, "trentino-süd-tirol": _2, "trentino-sudtirol": _2, "xn--trentino-sdtirol-szb": _2, "trentino-südtirol": _2, "trentino-sued-tirol": _2, "trentino-suedtirol": _2, "trentinoa-adige": _2, "trentinoaadige": _2, "trentinoalto-adige": _2, "trentinoaltoadige": _2, "trentinos-tirol": _2, "trentinostirol": _2, "trentinosud-tirol": _2, "xn--trentinosd-tirol-rzb": _2, "trentinosüd-tirol": _2, "trentinosudtirol": _2, "xn--trentinosdtirol-7vb": _2, "trentinosüdtirol": _2, "trentinosued-tirol": _2, "trentinosuedtirol": _2, "trentinsud-tirol": _2, "xn--trentinsd-tirol-6vb": _2, "trentinsüd-tirol": _2, "trentinsudtirol": _2, "xn--trentinsdtirol-nsb": _2, "trentinsüdtirol": _2, "trentinsued-tirol": _2, "trentinsuedtirol": _2, "tuscany": _2, "umb": _2, "umbria": _2, "val-d-aosta": _2, "val-daosta": _2, "vald-aosta": _2, "valdaosta": _2, "valle-aosta": _2, "valle-d-aosta": _2, "valle-daosta": _2, "valleaosta": _2, "valled-aosta": _2, "valledaosta": _2, "vallee-aoste": _2, "xn--valle-aoste-ebb": _2, "vallée-aoste": _2, "vallee-d-aoste": _2, "xn--valle-d-aoste-ehb": _2, "vallée-d-aoste": _2, "valleeaoste": _2, "xn--valleaoste-e7a": _2, "valléeaoste": _2, "valleedaoste": _2, "xn--valledaoste-ebb": _2, "valléedaoste": _2, "vao": _2, "vda": _2, "ven": _2, "veneto": _2, "ag": _2, "agrigento": _2, "al": _2, "alessandria": _2, "alto-adige": _2, "altoadige": _2, "an": _2, "ancona": _2, "andria-barletta-trani": _2, "andria-trani-barletta": _2, "andriabarlettatrani": _2, "andriatranibarletta": _2, "ao": _2, "aosta": _2, "aoste": _2, "ap": _2, "aq": _2, "aquila": _2, "ar": _2, "arezzo": _2, "ascoli-piceno": _2, "ascolipiceno": _2, "asti": _2, "at": _2, "av": _2, "avellino": _2, "ba": _2, "balsan": _2, "balsan-sudtirol": _2, "xn--balsan-sdtirol-nsb": _2, "balsan-südtirol": _2, "balsan-suedtirol": _2, "bari": _2, "barletta-trani-andria": _2, "barlettatraniandria": _2, "belluno": _2, "benevento": _2, "bergamo": _2, "bg": _2, "bi": _2, "biella": _2, "bl": _2, "bn": _2, "bo": _2, "bologna": _2, "bolzano": _2, "bolzano-altoadige": _2, "bozen": _2, "bozen-sudtirol": _2, "xn--bozen-sdtirol-2ob": _2, "bozen-südtirol": _2, "bozen-suedtirol": _2, "br": _2, "brescia": _2, "brindisi": _2, "bs": _2, "bt": _2, "bulsan": _2, "bulsan-sudtirol": _2, "xn--bulsan-sdtirol-nsb": _2, "bulsan-südtirol": _2, "bulsan-suedtirol": _2, "bz": _2, "ca": _2, "cagliari": _2, "caltanissetta": _2, "campidano-medio": _2, "campidanomedio": _2, "campobasso": _2, "carbonia-iglesias": _2, "carboniaiglesias": _2, "carrara-massa": _2, "carraramassa": _2, "caserta": _2, "catania": _2, "catanzaro": _2, "cb": _2, "ce": _2, "cesena-forli": _2, "xn--cesena-forl-mcb": _2, "cesena-forlì": _2, "cesenaforli": _2, "xn--cesenaforl-i8a": _2, "cesenaforlì": _2, "ch": _2, "chieti": _2, "ci": _2, "cl": _2, "cn": _2, "co": _2, "como": _2, "cosenza": _2, "cr": _2, "cremona": _2, "crotone": _2, "cs": _2, "ct": _2, "cuneo": _2, "cz": _2, "dell-ogliastra": _2, "dellogliastra": _2, "en": _2, "enna": _2, "fc": _2, "fe": _2, "fermo": _2, "ferrara": _2, "fg": _2, "fi": _2, "firenze": _2, "florence": _2, "fm": _2, "foggia": _2, "forli-cesena": _2, "xn--forl-cesena-fcb": _2, "forlì-cesena": _2, "forlicesena": _2, "xn--forlcesena-c8a": _2, "forlìcesena": _2, "fr": _2, "frosinone": _2, "ge": _2, "genoa": _2, "genova": _2, "go": _2, "gorizia": _2, "gr": _2, "grosseto": _2, "iglesias-carbonia": _2, "iglesiascarbonia": _2, "im": _2, "imperia": _2, "is": _2, "isernia": _2, "kr": _2, "la-spezia": _2, "laquila": _2, "laspezia": _2, "latina": _2, "lc": _2, "le": _2, "lecce": _2, "lecco": _2, "li": _2, "livorno": _2, "lo": _2, "lodi": _2, "lt": _2, "lu": _2, "lucca": _2, "macerata": _2, "mantova": _2, "massa-carrara": _2, "massacarrara": _2, "matera": _2, "mb": _2, "mc": _2, "me": _2, "medio-campidano": _2, "mediocampidano": _2, "messina": _2, "mi": _2, "milan": _2, "milano": _2, "mn": _2, "mo": _2, "modena": _2, "monza": _2, "monza-brianza": _2, "monza-e-della-brianza": _2, "monzabrianza": _2, "monzaebrianza": _2, "monzaedellabrianza": _2, "ms": _2, "mt": _2, "na": _2, "naples": _2, "napoli": _2, "no": _2, "novara": _2, "nu": _2, "nuoro": _2, "og": _2, "ogliastra": _2, "olbia-tempio": _2, "olbiatempio": _2, "or": _2, "oristano": _2, "ot": _2, "pa": _2, "padova": _2, "padua": _2, "palermo": _2, "parma": _2, "pavia": _2, "pc": _2, "pd": _2, "pe": _2, "perugia": _2, "pesaro-urbino": _2, "pesarourbino": _2, "pescara": _2, "pg": _2, "pi": _2, "piacenza": _2, "pisa": _2, "pistoia": _2, "pn": _2, "po": _2, "pordenone": _2, "potenza": _2, "pr": _2, "prato": _2, "pt": _2, "pu": _2, "pv": _2, "pz": _2, "ra": _2, "ragusa": _2, "ravenna": _2, "rc": _2, "re": _2, "reggio-calabria": _2, "reggio-emilia": _2, "reggiocalabria": _2, "reggioemilia": _2, "rg": _2, "ri": _2, "rieti": _2, "rimini": _2, "rm": _2, "rn": _2, "ro": _2, "roma": _2, "rome": _2, "rovigo": _2, "sa": _2, "salerno": _2, "sassari": _2, "savona": _2, "si": _2, "siena": _2, "siracusa": _2, "so": _2, "sondrio": _2, "sp": _2, "sr": _2, "ss": _2, "xn--sdtirol-n2a": _2, "südtirol": _2, "suedtirol": _2, "sv": _2, "ta": _2, "taranto": _2, "te": _2, "tempio-olbia": _2, "tempioolbia": _2, "teramo": _2, "terni": _2, "tn": _2, "to": _2, "torino": _2, "tp": _2, "tr": _2, "trani-andria-barletta": _2, "trani-barletta-andria": _2, "traniandriabarletta": _2, "tranibarlettaandria": _2, "trapani": _2, "trento": _2, "treviso": _2, "trieste": _2, "ts": _2, "turin": _2, "tv": _2, "ud": _2, "udine": _2, "urbino-pesaro": _2, "urbinopesaro": _2, "va": _2, "varese": _2, "vb": _2, "vc": _2, "ve": _2, "venezia": _2, "venice": _2, "verbania": _2, "vercelli": _2, "verona": _2, "vi": _2, "vibo-valentia": _2, "vibovalentia": _2, "vicenza": _2, "viterbo": _2, "vr": _2, "vs": _2, "vt": _2, "vv": _2, "12chars": _3, "ibxos": _3, "iliadboxos": _3, "neen": [0, { "jc": _3 }], "123homepage": _3, "16-b": _3, "32-b": _3, "64-b": _3, "myspreadshop": _3, "syncloud": _3 }], "je": [1, { "co": _2, "net": _2, "org": _2, "of": _3 }], "jm": _18, "jo": [1, { "agri": _2, "ai": _2, "com": _2, "edu": _2, "eng": _2, "fm": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "per": _2, "phd": _2, "sch": _2, "tv": _2 }], "jobs": _2, "jp": [1, { "ac": _2, "ad": _2, "co": _2, "ed": _2, "go": _2, "gr": _2, "lg": _2, "ne": [1, { "aseinet": _51, "gehirn": _3, "ivory": _3, "mail-box": _3, "mints": _3, "mokuren": _3, "opal": _3, "sakura": _3, "sumomo": _3, "topaz": _3 }], "or": _2, "aichi": [1, { "aisai": _2, "ama": _2, "anjo": _2, "asuke": _2, "chiryu": _2, "chita": _2, "fuso": _2, "gamagori": _2, "handa": _2, "hazu": _2, "hekinan": _2, "higashiura": _2, "ichinomiya": _2, "inazawa": _2, "inuyama": _2, "isshiki": _2, "iwakura": _2, "kanie": _2, "kariya": _2, "kasugai": _2, "kira": _2, "kiyosu": _2, "komaki": _2, "konan": _2, "kota": _2, "mihama": _2, "miyoshi": _2, "nishio": _2, "nisshin": _2, "obu": _2, "oguchi": _2, "oharu": _2, "okazaki": _2, "owariasahi": _2, "seto": _2, "shikatsu": _2, "shinshiro": _2, "shitara": _2, "tahara": _2, "takahama": _2, "tobishima": _2, "toei": _2, "togo": _2, "tokai": _2, "tokoname": _2, "toyoake": _2, "toyohashi": _2, "toyokawa": _2, "toyone": _2, "toyota": _2, "tsushima": _2, "yatomi": _2 }], "akita": [1, { "akita": _2, "daisen": _2, "fujisato": _2, "gojome": _2, "hachirogata": _2, "happou": _2, "higashinaruse": _2, "honjo": _2, "honjyo": _2, "ikawa": _2, "kamikoani": _2, "kamioka": _2, "katagami": _2, "kazuno": _2, "kitaakita": _2, "kosaka": _2, "kyowa": _2, "misato": _2, "mitane": _2, "moriyoshi": _2, "nikaho": _2, "noshiro": _2, "odate": _2, "oga": _2, "ogata": _2, "semboku": _2, "yokote": _2, "yurihonjo": _2 }], "aomori": [1, { "aomori": _2, "gonohe": _2, "hachinohe": _2, "hashikami": _2, "hiranai": _2, "hirosaki": _2, "itayanagi": _2, "kuroishi": _2, "misawa": _2, "mutsu": _2, "nakadomari": _2, "noheji": _2, "oirase": _2, "owani": _2, "rokunohe": _2, "sannohe": _2, "shichinohe": _2, "shingo": _2, "takko": _2, "towada": _2, "tsugaru": _2, "tsuruta": _2 }], "chiba": [1, { "abiko": _2, "asahi": _2, "chonan": _2, "chosei": _2, "choshi": _2, "chuo": _2, "funabashi": _2, "futtsu": _2, "hanamigawa": _2, "ichihara": _2, "ichikawa": _2, "ichinomiya": _2, "inzai": _2, "isumi": _2, "kamagaya": _2, "kamogawa": _2, "kashiwa": _2, "katori": _2, "katsuura": _2, "kimitsu": _2, "kisarazu": _2, "kozaki": _2, "kujukuri": _2, "kyonan": _2, "matsudo": _2, "midori": _2, "mihama": _2, "minamiboso": _2, "mobara": _2, "mutsuzawa": _2, "nagara": _2, "nagareyama": _2, "narashino": _2, "narita": _2, "noda": _2, "oamishirasato": _2, "omigawa": _2, "onjuku": _2, "otaki": _2, "sakae": _2, "sakura": _2, "shimofusa": _2, "shirako": _2, "shiroi": _2, "shisui": _2, "sodegaura": _2, "sosa": _2, "tako": _2, "tateyama": _2, "togane": _2, "tohnosho": _2, "tomisato": _2, "urayasu": _2, "yachimata": _2, "yachiyo": _2, "yokaichiba": _2, "yokoshibahikari": _2, "yotsukaido": _2 }], "ehime": [1, { "ainan": _2, "honai": _2, "ikata": _2, "imabari": _2, "iyo": _2, "kamijima": _2, "kihoku": _2, "kumakogen": _2, "masaki": _2, "matsuno": _2, "matsuyama": _2, "namikata": _2, "niihama": _2, "ozu": _2, "saijo": _2, "seiyo": _2, "shikokuchuo": _2, "tobe": _2, "toon": _2, "uchiko": _2, "uwajima": _2, "yawatahama": _2 }], "fukui": [1, { "echizen": _2, "eiheiji": _2, "fukui": _2, "ikeda": _2, "katsuyama": _2, "mihama": _2, "minamiechizen": _2, "obama": _2, "ohi": _2, "ono": _2, "sabae": _2, "sakai": _2, "takahama": _2, "tsuruga": _2, "wakasa": _2 }], "fukuoka": [1, { "ashiya": _2, "buzen": _2, "chikugo": _2, "chikuho": _2, "chikujo": _2, "chikushino": _2, "chikuzen": _2, "chuo": _2, "dazaifu": _2, "fukuchi": _2, "hakata": _2, "higashi": _2, "hirokawa": _2, "hisayama": _2, "iizuka": _2, "inatsuki": _2, "kaho": _2, "kasuga": _2, "kasuya": _2, "kawara": _2, "keisen": _2, "koga": _2, "kurate": _2, "kurogi": _2, "kurume": _2, "minami": _2, "miyako": _2, "miyama": _2, "miyawaka": _2, "mizumaki": _2, "munakata": _2, "nakagawa": _2, "nakama": _2, "nishi": _2, "nogata": _2, "ogori": _2, "okagaki": _2, "okawa": _2, "oki": _2, "omuta": _2, "onga": _2, "onojo": _2, "oto": _2, "saigawa": _2, "sasaguri": _2, "shingu": _2, "shinyoshitomi": _2, "shonai": _2, "soeda": _2, "sue": _2, "tachiarai": _2, "tagawa": _2, "takata": _2, "toho": _2, "toyotsu": _2, "tsuiki": _2, "ukiha": _2, "umi": _2, "usui": _2, "yamada": _2, "yame": _2, "yanagawa": _2, "yukuhashi": _2 }], "fukushima": [1, { "aizubange": _2, "aizumisato": _2, "aizuwakamatsu": _2, "asakawa": _2, "bandai": _2, "date": _2, "fukushima": _2, "furudono": _2, "futaba": _2, "hanawa": _2, "higashi": _2, "hirata": _2, "hirono": _2, "iitate": _2, "inawashiro": _2, "ishikawa": _2, "iwaki": _2, "izumizaki": _2, "kagamiishi": _2, "kaneyama": _2, "kawamata": _2, "kitakata": _2, "kitashiobara": _2, "koori": _2, "koriyama": _2, "kunimi": _2, "miharu": _2, "mishima": _2, "namie": _2, "nango": _2, "nishiaizu": _2, "nishigo": _2, "okuma": _2, "omotego": _2, "ono": _2, "otama": _2, "samegawa": _2, "shimogo": _2, "shirakawa": _2, "showa": _2, "soma": _2, "sukagawa": _2, "taishin": _2, "tamakawa": _2, "tanagura": _2, "tenei": _2, "yabuki": _2, "yamato": _2, "yamatsuri": _2, "yanaizu": _2, "yugawa": _2 }], "gifu": [1, { "anpachi": _2, "ena": _2, "gifu": _2, "ginan": _2, "godo": _2, "gujo": _2, "hashima": _2, "hichiso": _2, "hida": _2, "higashishirakawa": _2, "ibigawa": _2, "ikeda": _2, "kakamigahara": _2, "kani": _2, "kasahara": _2, "kasamatsu": _2, "kawaue": _2, "kitagata": _2, "mino": _2, "minokamo": _2, "mitake": _2, "mizunami": _2, "motosu": _2, "nakatsugawa": _2, "ogaki": _2, "sakahogi": _2, "seki": _2, "sekigahara": _2, "shirakawa": _2, "tajimi": _2, "takayama": _2, "tarui": _2, "toki": _2, "tomika": _2, "wanouchi": _2, "yamagata": _2, "yaotsu": _2, "yoro": _2 }], "gunma": [1, { "annaka": _2, "chiyoda": _2, "fujioka": _2, "higashiagatsuma": _2, "isesaki": _2, "itakura": _2, "kanna": _2, "kanra": _2, "katashina": _2, "kawaba": _2, "kiryu": _2, "kusatsu": _2, "maebashi": _2, "meiwa": _2, "midori": _2, "minakami": _2, "naganohara": _2, "nakanojo": _2, "nanmoku": _2, "numata": _2, "oizumi": _2, "ora": _2, "ota": _2, "shibukawa": _2, "shimonita": _2, "shinto": _2, "showa": _2, "takasaki": _2, "takayama": _2, "tamamura": _2, "tatebayashi": _2, "tomioka": _2, "tsukiyono": _2, "tsumagoi": _2, "ueno": _2, "yoshioka": _2 }], "hiroshima": [1, { "asaminami": _2, "daiwa": _2, "etajima": _2, "fuchu": _2, "fukuyama": _2, "hatsukaichi": _2, "higashihiroshima": _2, "hongo": _2, "jinsekikogen": _2, "kaita": _2, "kui": _2, "kumano": _2, "kure": _2, "mihara": _2, "miyoshi": _2, "naka": _2, "onomichi": _2, "osakikamijima": _2, "otake": _2, "saka": _2, "sera": _2, "seranishi": _2, "shinichi": _2, "shobara": _2, "takehara": _2 }], "hokkaido": [1, { "abashiri": _2, "abira": _2, "aibetsu": _2, "akabira": _2, "akkeshi": _2, "asahikawa": _2, "ashibetsu": _2, "ashoro": _2, "assabu": _2, "atsuma": _2, "bibai": _2, "biei": _2, "bifuka": _2, "bihoro": _2, "biratori": _2, "chippubetsu": _2, "chitose": _2, "date": _2, "ebetsu": _2, "embetsu": _2, "eniwa": _2, "erimo": _2, "esan": _2, "esashi": _2, "fukagawa": _2, "fukushima": _2, "furano": _2, "furubira": _2, "haboro": _2, "hakodate": _2, "hamatonbetsu": _2, "hidaka": _2, "higashikagura": _2, "higashikawa": _2, "hiroo": _2, "hokuryu": _2, "hokuto": _2, "honbetsu": _2, "horokanai": _2, "horonobe": _2, "ikeda": _2, "imakane": _2, "ishikari": _2, "iwamizawa": _2, "iwanai": _2, "kamifurano": _2, "kamikawa": _2, "kamishihoro": _2, "kamisunagawa": _2, "kamoenai": _2, "kayabe": _2, "kembuchi": _2, "kikonai": _2, "kimobetsu": _2, "kitahiroshima": _2, "kitami": _2, "kiyosato": _2, "koshimizu": _2, "kunneppu": _2, "kuriyama": _2, "kuromatsunai": _2, "kushiro": _2, "kutchan": _2, "kyowa": _2, "mashike": _2, "matsumae": _2, "mikasa": _2, "minamifurano": _2, "mombetsu": _2, "moseushi": _2, "mukawa": _2, "muroran": _2, "naie": _2, "nakagawa": _2, "nakasatsunai": _2, "nakatombetsu": _2, "nanae": _2, "nanporo": _2, "nayoro": _2, "nemuro": _2, "niikappu": _2, "niki": _2, "nishiokoppe": _2, "noboribetsu": _2, "numata": _2, "obihiro": _2, "obira": _2, "oketo": _2, "okoppe": _2, "otaru": _2, "otobe": _2, "otofuke": _2, "otoineppu": _2, "oumu": _2, "ozora": _2, "pippu": _2, "rankoshi": _2, "rebun": _2, "rikubetsu": _2, "rishiri": _2, "rishirifuji": _2, "saroma": _2, "sarufutsu": _2, "shakotan": _2, "shari": _2, "shibecha": _2, "shibetsu": _2, "shikabe": _2, "shikaoi": _2, "shimamaki": _2, "shimizu": _2, "shimokawa": _2, "shinshinotsu": _2, "shintoku": _2, "shiranuka": _2, "shiraoi": _2, "shiriuchi": _2, "sobetsu": _2, "sunagawa": _2, "taiki": _2, "takasu": _2, "takikawa": _2, "takinoue": _2, "teshikaga": _2, "tobetsu": _2, "tohma": _2, "tomakomai": _2, "tomari": _2, "toya": _2, "toyako": _2, "toyotomi": _2, "toyoura": _2, "tsubetsu": _2, "tsukigata": _2, "urakawa": _2, "urausu": _2, "uryu": _2, "utashinai": _2, "wakkanai": _2, "wassamu": _2, "yakumo": _2, "yoichi": _2 }], "hyogo": [1, { "aioi": _2, "akashi": _2, "ako": _2, "amagasaki": _2, "aogaki": _2, "asago": _2, "ashiya": _2, "awaji": _2, "fukusaki": _2, "goshiki": _2, "harima": _2, "himeji": _2, "ichikawa": _2, "inagawa": _2, "itami": _2, "kakogawa": _2, "kamigori": _2, "kamikawa": _2, "kasai": _2, "kasuga": _2, "kawanishi": _2, "miki": _2, "minamiawaji": _2, "nishinomiya": _2, "nishiwaki": _2, "ono": _2, "sanda": _2, "sannan": _2, "sasayama": _2, "sayo": _2, "shingu": _2, "shinonsen": _2, "shiso": _2, "sumoto": _2, "taishi": _2, "taka": _2, "takarazuka": _2, "takasago": _2, "takino": _2, "tamba": _2, "tatsuno": _2, "toyooka": _2, "yabu": _2, "yashiro": _2, "yoka": _2, "yokawa": _2 }], "ibaraki": [1, { "ami": _2, "asahi": _2, "bando": _2, "chikusei": _2, "daigo": _2, "fujishiro": _2, "hitachi": _2, "hitachinaka": _2, "hitachiomiya": _2, "hitachiota": _2, "ibaraki": _2, "ina": _2, "inashiki": _2, "itako": _2, "iwama": _2, "joso": _2, "kamisu": _2, "kasama": _2, "kashima": _2, "kasumigaura": _2, "koga": _2, "miho": _2, "mito": _2, "moriya": _2, "naka": _2, "namegata": _2, "oarai": _2, "ogawa": _2, "omitama": _2, "ryugasaki": _2, "sakai": _2, "sakuragawa": _2, "shimodate": _2, "shimotsuma": _2, "shirosato": _2, "sowa": _2, "suifu": _2, "takahagi": _2, "tamatsukuri": _2, "tokai": _2, "tomobe": _2, "tone": _2, "toride": _2, "tsuchiura": _2, "tsukuba": _2, "uchihara": _2, "ushiku": _2, "yachiyo": _2, "yamagata": _2, "yawara": _2, "yuki": _2 }], "ishikawa": [1, { "anamizu": _2, "hakui": _2, "hakusan": _2, "kaga": _2, "kahoku": _2, "kanazawa": _2, "kawakita": _2, "komatsu": _2, "nakanoto": _2, "nanao": _2, "nomi": _2, "nonoichi": _2, "noto": _2, "shika": _2, "suzu": _2, "tsubata": _2, "tsurugi": _2, "uchinada": _2, "wajima": _2 }], "iwate": [1, { "fudai": _2, "fujisawa": _2, "hanamaki": _2, "hiraizumi": _2, "hirono": _2, "ichinohe": _2, "ichinoseki": _2, "iwaizumi": _2, "iwate": _2, "joboji": _2, "kamaishi": _2, "kanegasaki": _2, "karumai": _2, "kawai": _2, "kitakami": _2, "kuji": _2, "kunohe": _2, "kuzumaki": _2, "miyako": _2, "mizusawa": _2, "morioka": _2, "ninohe": _2, "noda": _2, "ofunato": _2, "oshu": _2, "otsuchi": _2, "rikuzentakata": _2, "shiwa": _2, "shizukuishi": _2, "sumita": _2, "tanohata": _2, "tono": _2, "yahaba": _2, "yamada": _2 }], "kagawa": [1, { "ayagawa": _2, "higashikagawa": _2, "kanonji": _2, "kotohira": _2, "manno": _2, "marugame": _2, "mitoyo": _2, "naoshima": _2, "sanuki": _2, "tadotsu": _2, "takamatsu": _2, "tonosho": _2, "uchinomi": _2, "utazu": _2, "zentsuji": _2 }], "kagoshima": [1, { "akune": _2, "amami": _2, "hioki": _2, "isa": _2, "isen": _2, "izumi": _2, "kagoshima": _2, "kanoya": _2, "kawanabe": _2, "kinko": _2, "kouyama": _2, "makurazaki": _2, "matsumoto": _2, "minamitane": _2, "nakatane": _2, "nishinoomote": _2, "satsumasendai": _2, "soo": _2, "tarumizu": _2, "yusui": _2 }], "kanagawa": [1, { "aikawa": _2, "atsugi": _2, "ayase": _2, "chigasaki": _2, "ebina": _2, "fujisawa": _2, "hadano": _2, "hakone": _2, "hiratsuka": _2, "isehara": _2, "kaisei": _2, "kamakura": _2, "kiyokawa": _2, "matsuda": _2, "minamiashigara": _2, "miura": _2, "nakai": _2, "ninomiya": _2, "odawara": _2, "oi": _2, "oiso": _2, "sagamihara": _2, "samukawa": _2, "tsukui": _2, "yamakita": _2, "yamato": _2, "yokosuka": _2, "yugawara": _2, "zama": _2, "zushi": _2 }], "kochi": [1, { "aki": _2, "geisei": _2, "hidaka": _2, "higashitsuno": _2, "ino": _2, "kagami": _2, "kami": _2, "kitagawa": _2, "kochi": _2, "mihara": _2, "motoyama": _2, "muroto": _2, "nahari": _2, "nakamura": _2, "nankoku": _2, "nishitosa": _2, "niyodogawa": _2, "ochi": _2, "okawa": _2, "otoyo": _2, "otsuki": _2, "sakawa": _2, "sukumo": _2, "susaki": _2, "tosa": _2, "tosashimizu": _2, "toyo": _2, "tsuno": _2, "umaji": _2, "yasuda": _2, "yusuhara": _2 }], "kumamoto": [1, { "amakusa": _2, "arao": _2, "aso": _2, "choyo": _2, "gyokuto": _2, "kamiamakusa": _2, "kikuchi": _2, "kumamoto": _2, "mashiki": _2, "mifune": _2, "minamata": _2, "minamioguni": _2, "nagasu": _2, "nishihara": _2, "oguni": _2, "ozu": _2, "sumoto": _2, "takamori": _2, "uki": _2, "uto": _2, "yamaga": _2, "yamato": _2, "yatsushiro": _2 }], "kyoto": [1, { "ayabe": _2, "fukuchiyama": _2, "higashiyama": _2, "ide": _2, "ine": _2, "joyo": _2, "kameoka": _2, "kamo": _2, "kita": _2, "kizu": _2, "kumiyama": _2, "kyotamba": _2, "kyotanabe": _2, "kyotango": _2, "maizuru": _2, "minami": _2, "minamiyamashiro": _2, "miyazu": _2, "muko": _2, "nagaokakyo": _2, "nakagyo": _2, "nantan": _2, "oyamazaki": _2, "sakyo": _2, "seika": _2, "tanabe": _2, "uji": _2, "ujitawara": _2, "wazuka": _2, "yamashina": _2, "yawata": _2 }], "mie": [1, { "asahi": _2, "inabe": _2, "ise": _2, "kameyama": _2, "kawagoe": _2, "kiho": _2, "kisosaki": _2, "kiwa": _2, "komono": _2, "kumano": _2, "kuwana": _2, "matsusaka": _2, "meiwa": _2, "mihama": _2, "minamiise": _2, "misugi": _2, "miyama": _2, "nabari": _2, "shima": _2, "suzuka": _2, "tado": _2, "taiki": _2, "taki": _2, "tamaki": _2, "toba": _2, "tsu": _2, "udono": _2, "ureshino": _2, "watarai": _2, "yokkaichi": _2 }], "miyagi": [1, { "furukawa": _2, "higashimatsushima": _2, "ishinomaki": _2, "iwanuma": _2, "kakuda": _2, "kami": _2, "kawasaki": _2, "marumori": _2, "matsushima": _2, "minamisanriku": _2, "misato": _2, "murata": _2, "natori": _2, "ogawara": _2, "ohira": _2, "onagawa": _2, "osaki": _2, "rifu": _2, "semine": _2, "shibata": _2, "shichikashuku": _2, "shikama": _2, "shiogama": _2, "shiroishi": _2, "tagajo": _2, "taiwa": _2, "tome": _2, "tomiya": _2, "wakuya": _2, "watari": _2, "yamamoto": _2, "zao": _2 }], "miyazaki": [1, { "aya": _2, "ebino": _2, "gokase": _2, "hyuga": _2, "kadogawa": _2, "kawaminami": _2, "kijo": _2, "kitagawa": _2, "kitakata": _2, "kitaura": _2, "kobayashi": _2, "kunitomi": _2, "kushima": _2, "mimata": _2, "miyakonojo": _2, "miyazaki": _2, "morotsuka": _2, "nichinan": _2, "nishimera": _2, "nobeoka": _2, "saito": _2, "shiiba": _2, "shintomi": _2, "takaharu": _2, "takanabe": _2, "takazaki": _2, "tsuno": _2 }], "nagano": [1, { "achi": _2, "agematsu": _2, "anan": _2, "aoki": _2, "asahi": _2, "azumino": _2, "chikuhoku": _2, "chikuma": _2, "chino": _2, "fujimi": _2, "hakuba": _2, "hara": _2, "hiraya": _2, "iida": _2, "iijima": _2, "iiyama": _2, "iizuna": _2, "ikeda": _2, "ikusaka": _2, "ina": _2, "karuizawa": _2, "kawakami": _2, "kiso": _2, "kisofukushima": _2, "kitaaiki": _2, "komagane": _2, "komoro": _2, "matsukawa": _2, "matsumoto": _2, "miasa": _2, "minamiaiki": _2, "minamimaki": _2, "minamiminowa": _2, "minowa": _2, "miyada": _2, "miyota": _2, "mochizuki": _2, "nagano": _2, "nagawa": _2, "nagiso": _2, "nakagawa": _2, "nakano": _2, "nozawaonsen": _2, "obuse": _2, "ogawa": _2, "okaya": _2, "omachi": _2, "omi": _2, "ookuwa": _2, "ooshika": _2, "otaki": _2, "otari": _2, "sakae": _2, "sakaki": _2, "saku": _2, "sakuho": _2, "shimosuwa": _2, "shinanomachi": _2, "shiojiri": _2, "suwa": _2, "suzaka": _2, "takagi": _2, "takamori": _2, "takayama": _2, "tateshina": _2, "tatsuno": _2, "togakushi": _2, "togura": _2, "tomi": _2, "ueda": _2, "wada": _2, "yamagata": _2, "yamanouchi": _2, "yasaka": _2, "yasuoka": _2 }], "nagasaki": [1, { "chijiwa": _2, "futsu": _2, "goto": _2, "hasami": _2, "hirado": _2, "iki": _2, "isahaya": _2, "kawatana": _2, "kuchinotsu": _2, "matsuura": _2, "nagasaki": _2, "obama": _2, "omura": _2, "oseto": _2, "saikai": _2, "sasebo": _2, "seihi": _2, "shimabara": _2, "shinkamigoto": _2, "togitsu": _2, "tsushima": _2, "unzen": _2 }], "nara": [1, { "ando": _2, "gose": _2, "heguri": _2, "higashiyoshino": _2, "ikaruga": _2, "ikoma": _2, "kamikitayama": _2, "kanmaki": _2, "kashiba": _2, "kashihara": _2, "katsuragi": _2, "kawai": _2, "kawakami": _2, "kawanishi": _2, "koryo": _2, "kurotaki": _2, "mitsue": _2, "miyake": _2, "nara": _2, "nosegawa": _2, "oji": _2, "ouda": _2, "oyodo": _2, "sakurai": _2, "sango": _2, "shimoichi": _2, "shimokitayama": _2, "shinjo": _2, "soni": _2, "takatori": _2, "tawaramoto": _2, "tenkawa": _2, "tenri": _2, "uda": _2, "yamatokoriyama": _2, "yamatotakada": _2, "yamazoe": _2, "yoshino": _2 }], "niigata": [1, { "aga": _2, "agano": _2, "gosen": _2, "itoigawa": _2, "izumozaki": _2, "joetsu": _2, "kamo": _2, "kariwa": _2, "kashiwazaki": _2, "minamiuonuma": _2, "mitsuke": _2, "muika": _2, "murakami": _2, "myoko": _2, "nagaoka": _2, "niigata": _2, "ojiya": _2, "omi": _2, "sado": _2, "sanjo": _2, "seiro": _2, "seirou": _2, "sekikawa": _2, "shibata": _2, "tagami": _2, "tainai": _2, "tochio": _2, "tokamachi": _2, "tsubame": _2, "tsunan": _2, "uonuma": _2, "yahiko": _2, "yoita": _2, "yuzawa": _2 }], "oita": [1, { "beppu": _2, "bungoono": _2, "bungotakada": _2, "hasama": _2, "hiji": _2, "himeshima": _2, "hita": _2, "kamitsue": _2, "kokonoe": _2, "kuju": _2, "kunisaki": _2, "kusu": _2, "oita": _2, "saiki": _2, "taketa": _2, "tsukumi": _2, "usa": _2, "usuki": _2, "yufu": _2 }], "okayama": [1, { "akaiwa": _2, "asakuchi": _2, "bizen": _2, "hayashima": _2, "ibara": _2, "kagamino": _2, "kasaoka": _2, "kibichuo": _2, "kumenan": _2, "kurashiki": _2, "maniwa": _2, "misaki": _2, "nagi": _2, "niimi": _2, "nishiawakura": _2, "okayama": _2, "satosho": _2, "setouchi": _2, "shinjo": _2, "shoo": _2, "soja": _2, "takahashi": _2, "tamano": _2, "tsuyama": _2, "wake": _2, "yakage": _2 }], "okinawa": [1, { "aguni": _2, "ginowan": _2, "ginoza": _2, "gushikami": _2, "haebaru": _2, "higashi": _2, "hirara": _2, "iheya": _2, "ishigaki": _2, "ishikawa": _2, "itoman": _2, "izena": _2, "kadena": _2, "kin": _2, "kitadaito": _2, "kitanakagusuku": _2, "kumejima": _2, "kunigami": _2, "minamidaito": _2, "motobu": _2, "nago": _2, "naha": _2, "nakagusuku": _2, "nakijin": _2, "nanjo": _2, "nishihara": _2, "ogimi": _2, "okinawa": _2, "onna": _2, "shimoji": _2, "taketomi": _2, "tarama": _2, "tokashiki": _2, "tomigusuku": _2, "tonaki": _2, "urasoe": _2, "uruma": _2, "yaese": _2, "yomitan": _2, "yonabaru": _2, "yonaguni": _2, "zamami": _2 }], "osaka": [1, { "abeno": _2, "chihayaakasaka": _2, "chuo": _2, "daito": _2, "fujiidera": _2, "habikino": _2, "hannan": _2, "higashiosaka": _2, "higashisumiyoshi": _2, "higashiyodogawa": _2, "hirakata": _2, "ibaraki": _2, "ikeda": _2, "izumi": _2, "izumiotsu": _2, "izumisano": _2, "kadoma": _2, "kaizuka": _2, "kanan": _2, "kashiwara": _2, "katano": _2, "kawachinagano": _2, "kishiwada": _2, "kita": _2, "kumatori": _2, "matsubara": _2, "minato": _2, "minoh": _2, "misaki": _2, "moriguchi": _2, "neyagawa": _2, "nishi": _2, "nose": _2, "osakasayama": _2, "sakai": _2, "sayama": _2, "sennan": _2, "settsu": _2, "shijonawate": _2, "shimamoto": _2, "suita": _2, "tadaoka": _2, "taishi": _2, "tajiri": _2, "takaishi": _2, "takatsuki": _2, "tondabayashi": _2, "toyonaka": _2, "toyono": _2, "yao": _2 }], "saga": [1, { "ariake": _2, "arita": _2, "fukudomi": _2, "genkai": _2, "hamatama": _2, "hizen": _2, "imari": _2, "kamimine": _2, "kanzaki": _2, "karatsu": _2, "kashima": _2, "kitagata": _2, "kitahata": _2, "kiyama": _2, "kouhoku": _2, "kyuragi": _2, "nishiarita": _2, "ogi": _2, "omachi": _2, "ouchi": _2, "saga": _2, "shiroishi": _2, "taku": _2, "tara": _2, "tosu": _2, "yoshinogari": _2 }], "saitama": [1, { "arakawa": _2, "asaka": _2, "chichibu": _2, "fujimi": _2, "fujimino": _2, "fukaya": _2, "hanno": _2, "hanyu": _2, "hasuda": _2, "hatogaya": _2, "hatoyama": _2, "hidaka": _2, "higashichichibu": _2, "higashimatsuyama": _2, "honjo": _2, "ina": _2, "iruma": _2, "iwatsuki": _2, "kamiizumi": _2, "kamikawa": _2, "kamisato": _2, "kasukabe": _2, "kawagoe": _2, "kawaguchi": _2, "kawajima": _2, "kazo": _2, "kitamoto": _2, "koshigaya": _2, "kounosu": _2, "kuki": _2, "kumagaya": _2, "matsubushi": _2, "minano": _2, "misato": _2, "miyashiro": _2, "miyoshi": _2, "moroyama": _2, "nagatoro": _2, "namegawa": _2, "niiza": _2, "ogano": _2, "ogawa": _2, "ogose": _2, "okegawa": _2, "omiya": _2, "otaki": _2, "ranzan": _2, "ryokami": _2, "saitama": _2, "sakado": _2, "satte": _2, "sayama": _2, "shiki": _2, "shiraoka": _2, "soka": _2, "sugito": _2, "toda": _2, "tokigawa": _2, "tokorozawa": _2, "tsurugashima": _2, "urawa": _2, "warabi": _2, "yashio": _2, "yokoze": _2, "yono": _2, "yorii": _2, "yoshida": _2, "yoshikawa": _2, "yoshimi": _2 }], "shiga": [1, { "aisho": _2, "gamo": _2, "higashiomi": _2, "hikone": _2, "koka": _2, "konan": _2, "kosei": _2, "koto": _2, "kusatsu": _2, "maibara": _2, "moriyama": _2, "nagahama": _2, "nishiazai": _2, "notogawa": _2, "omihachiman": _2, "otsu": _2, "ritto": _2, "ryuoh": _2, "takashima": _2, "takatsuki": _2, "torahime": _2, "toyosato": _2, "yasu": _2 }], "shimane": [1, { "akagi": _2, "ama": _2, "gotsu": _2, "hamada": _2, "higashiizumo": _2, "hikawa": _2, "hikimi": _2, "izumo": _2, "kakinoki": _2, "masuda": _2, "matsue": _2, "misato": _2, "nishinoshima": _2, "ohda": _2, "okinoshima": _2, "okuizumo": _2, "shimane": _2, "tamayu": _2, "tsuwano": _2, "unnan": _2, "yakumo": _2, "yasugi": _2, "yatsuka": _2 }], "shizuoka": [1, { "arai": _2, "atami": _2, "fuji": _2, "fujieda": _2, "fujikawa": _2, "fujinomiya": _2, "fukuroi": _2, "gotemba": _2, "haibara": _2, "hamamatsu": _2, "higashiizu": _2, "ito": _2, "iwata": _2, "izu": _2, "izunokuni": _2, "kakegawa": _2, "kannami": _2, "kawanehon": _2, "kawazu": _2, "kikugawa": _2, "kosai": _2, "makinohara": _2, "matsuzaki": _2, "minamiizu": _2, "mishima": _2, "morimachi": _2, "nishiizu": _2, "numazu": _2, "omaezaki": _2, "shimada": _2, "shimizu": _2, "shimoda": _2, "shizuoka": _2, "susono": _2, "yaizu": _2, "yoshida": _2 }], "tochigi": [1, { "ashikaga": _2, "bato": _2, "haga": _2, "ichikai": _2, "iwafune": _2, "kaminokawa": _2, "kanuma": _2, "karasuyama": _2, "kuroiso": _2, "mashiko": _2, "mibu": _2, "moka": _2, "motegi": _2, "nasu": _2, "nasushiobara": _2, "nikko": _2, "nishikata": _2, "nogi": _2, "ohira": _2, "ohtawara": _2, "oyama": _2, "sakura": _2, "sano": _2, "shimotsuke": _2, "shioya": _2, "takanezawa": _2, "tochigi": _2, "tsuga": _2, "ujiie": _2, "utsunomiya": _2, "yaita": _2 }], "tokushima": [1, { "aizumi": _2, "anan": _2, "ichiba": _2, "itano": _2, "kainan": _2, "komatsushima": _2, "matsushige": _2, "mima": _2, "minami": _2, "miyoshi": _2, "mugi": _2, "nakagawa": _2, "naruto": _2, "sanagochi": _2, "shishikui": _2, "tokushima": _2, "wajiki": _2 }], "tokyo": [1, { "adachi": _2, "akiruno": _2, "akishima": _2, "aogashima": _2, "arakawa": _2, "bunkyo": _2, "chiyoda": _2, "chofu": _2, "chuo": _2, "edogawa": _2, "fuchu": _2, "fussa": _2, "hachijo": _2, "hachioji": _2, "hamura": _2, "higashikurume": _2, "higashimurayama": _2, "higashiyamato": _2, "hino": _2, "hinode": _2, "hinohara": _2, "inagi": _2, "itabashi": _2, "katsushika": _2, "kita": _2, "kiyose": _2, "kodaira": _2, "koganei": _2, "kokubunji": _2, "komae": _2, "koto": _2, "kouzushima": _2, "kunitachi": _2, "machida": _2, "meguro": _2, "minato": _2, "mitaka": _2, "mizuho": _2, "musashimurayama": _2, "musashino": _2, "nakano": _2, "nerima": _2, "ogasawara": _2, "okutama": _2, "ome": _2, "oshima": _2, "ota": _2, "setagaya": _2, "shibuya": _2, "shinagawa": _2, "shinjuku": _2, "suginami": _2, "sumida": _2, "tachikawa": _2, "taito": _2, "tama": _2, "toshima": _2 }], "tottori": [1, { "chizu": _2, "hino": _2, "kawahara": _2, "koge": _2, "kotoura": _2, "misasa": _2, "nanbu": _2, "nichinan": _2, "sakaiminato": _2, "tottori": _2, "wakasa": _2, "yazu": _2, "yonago": _2 }], "toyama": [1, { "asahi": _2, "fuchu": _2, "fukumitsu": _2, "funahashi": _2, "himi": _2, "imizu": _2, "inami": _2, "johana": _2, "kamiichi": _2, "kurobe": _2, "nakaniikawa": _2, "namerikawa": _2, "nanto": _2, "nyuzen": _2, "oyabe": _2, "taira": _2, "takaoka": _2, "tateyama": _2, "toga": _2, "tonami": _2, "toyama": _2, "unazuki": _2, "uozu": _2, "yamada": _2 }], "wakayama": [1, { "arida": _2, "aridagawa": _2, "gobo": _2, "hashimoto": _2, "hidaka": _2, "hirogawa": _2, "inami": _2, "iwade": _2, "kainan": _2, "kamitonda": _2, "katsuragi": _2, "kimino": _2, "kinokawa": _2, "kitayama": _2, "koya": _2, "koza": _2, "kozagawa": _2, "kudoyama": _2, "kushimoto": _2, "mihama": _2, "misato": _2, "nachikatsuura": _2, "shingu": _2, "shirahama": _2, "taiji": _2, "tanabe": _2, "wakayama": _2, "yuasa": _2, "yura": _2 }], "yamagata": [1, { "asahi": _2, "funagata": _2, "higashine": _2, "iide": _2, "kahoku": _2, "kaminoyama": _2, "kaneyama": _2, "kawanishi": _2, "mamurogawa": _2, "mikawa": _2, "murayama": _2, "nagai": _2, "nakayama": _2, "nanyo": _2, "nishikawa": _2, "obanazawa": _2, "oe": _2, "oguni": _2, "ohkura": _2, "oishida": _2, "sagae": _2, "sakata": _2, "sakegawa": _2, "shinjo": _2, "shirataka": _2, "shonai": _2, "takahata": _2, "tendo": _2, "tozawa": _2, "tsuruoka": _2, "yamagata": _2, "yamanobe": _2, "yonezawa": _2, "yuza": _2 }], "yamaguchi": [1, { "abu": _2, "hagi": _2, "hikari": _2, "hofu": _2, "iwakuni": _2, "kudamatsu": _2, "mitou": _2, "nagato": _2, "oshima": _2, "shimonoseki": _2, "shunan": _2, "tabuse": _2, "tokuyama": _2, "toyota": _2, "ube": _2, "yuu": _2 }], "yamanashi": [1, { "chuo": _2, "doshi": _2, "fuefuki": _2, "fujikawa": _2, "fujikawaguchiko": _2, "fujiyoshida": _2, "hayakawa": _2, "hokuto": _2, "ichikawamisato": _2, "kai": _2, "kofu": _2, "koshu": _2, "kosuge": _2, "minami-alps": _2, "minobu": _2, "nakamichi": _2, "nanbu": _2, "narusawa": _2, "nirasaki": _2, "nishikatsura": _2, "oshino": _2, "otsuki": _2, "showa": _2, "tabayama": _2, "tsuru": _2, "uenohara": _2, "yamanakako": _2, "yamanashi": _2 }], "xn--ehqz56n": _2, "三重": _2, "xn--1lqs03n": _2, "京都": _2, "xn--qqqt11m": _2, "佐賀": _2, "xn--f6qx53a": _2, "兵庫": _2, "xn--djrs72d6uy": _2, "北海道": _2, "xn--mkru45i": _2, "千葉": _2, "xn--0trq7p7nn": _2, "和歌山": _2, "xn--5js045d": _2, "埼玉": _2, "xn--kbrq7o": _2, "大分": _2, "xn--pssu33l": _2, "大阪": _2, "xn--ntsq17g": _2, "奈良": _2, "xn--uisz3g": _2, "宮城": _2, "xn--6btw5a": _2, "宮崎": _2, "xn--1ctwo": _2, "富山": _2, "xn--6orx2r": _2, "山口": _2, "xn--rht61e": _2, "山形": _2, "xn--rht27z": _2, "山梨": _2, "xn--nit225k": _2, "岐阜": _2, "xn--rht3d": _2, "岡山": _2, "xn--djty4k": _2, "岩手": _2, "xn--klty5x": _2, "島根": _2, "xn--kltx9a": _2, "広島": _2, "xn--kltp7d": _2, "徳島": _2, "xn--c3s14m": _2, "愛媛": _2, "xn--vgu402c": _2, "愛知": _2, "xn--efvn9s": _2, "新潟": _2, "xn--1lqs71d": _2, "東京": _2, "xn--4pvxs": _2, "栃木": _2, "xn--uuwu58a": _2, "沖縄": _2, "xn--zbx025d": _2, "滋賀": _2, "xn--8pvr4u": _2, "熊本": _2, "xn--5rtp49c": _2, "石川": _2, "xn--ntso0iqx3a": _2, "神奈川": _2, "xn--elqq16h": _2, "福井": _2, "xn--4it168d": _2, "福岡": _2, "xn--klt787d": _2, "福島": _2, "xn--rny31h": _2, "秋田": _2, "xn--7t0a264c": _2, "群馬": _2, "xn--uist22h": _2, "茨城": _2, "xn--8ltr62k": _2, "長崎": _2, "xn--2m4a15e": _2, "長野": _2, "xn--32vp30h": _2, "青森": _2, "xn--4it797k": _2, "静岡": _2, "xn--5rtq34k": _2, "香川": _2, "xn--k7yn95e": _2, "高知": _2, "xn--tor131o": _2, "鳥取": _2, "xn--d5qv7z876c": _2, "鹿児島": _2, "kawasaki": _18, "kitakyushu": _18, "kobe": _18, "nagoya": _18, "sapporo": _18, "sendai": _18, "yokohama": _18, "buyshop": _3, "fashionstore": _3, "handcrafted": _3, "kawaiishop": _3, "supersale": _3, "theshop": _3, "0am": _3, "0g0": _3, "0j0": _3, "0t0": _3, "mydns": _3, "pgw": _3, "wjg": _3, "usercontent": _3, "angry": _3, "babyblue": _3, "babymilk": _3, "backdrop": _3, "bambina": _3, "bitter": _3, "blush": _3, "boo": _3, "boy": _3, "boyfriend": _3, "but": _3, "candypop": _3, "capoo": _3, "catfood": _3, "cheap": _3, "chicappa": _3, "chillout": _3, "chips": _3, "chowder": _3, "chu": _3, "ciao": _3, "cocotte": _3, "coolblog": _3, "cranky": _3, "cutegirl": _3, "daa": _3, "deca": _3, "deci": _3, "digick": _3, "egoism": _3, "fakefur": _3, "fem": _3, "flier": _3, "floppy": _3, "fool": _3, "frenchkiss": _3, "girlfriend": _3, "girly": _3, "gloomy": _3, "gonna": _3, "greater": _3, "hacca": _3, "heavy": _3, "her": _3, "hiho": _3, "hippy": _3, "holy": _3, "hungry": _3, "icurus": _3, "itigo": _3, "jellybean": _3, "kikirara": _3, "kill": _3, "kilo": _3, "kuron": _3, "littlestar": _3, "lolipopmc": _3, "lolitapunk": _3, "lomo": _3, "lovepop": _3, "lovesick": _3, "main": _3, "mods": _3, "mond": _3, "mongolian": _3, "moo": _3, "namaste": _3, "nikita": _3, "nobushi": _3, "noor": _3, "oops": _3, "parallel": _3, "parasite": _3, "pecori": _3, "peewee": _3, "penne": _3, "pepper": _3, "perma": _3, "pigboat": _3, "pinoko": _3, "punyu": _3, "pupu": _3, "pussycat": _3, "pya": _3, "raindrop": _3, "readymade": _3, "sadist": _3, "schoolbus": _3, "secret": _3, "staba": _3, "stripper": _3, "sub": _3, "sunnyday": _3, "thick": _3, "tonkotsu": _3, "under": _3, "upper": _3, "velvet": _3, "verse": _3, "versus": _3, "vivian": _3, "watson": _3, "weblike": _3, "whitesnow": _3, "zombie": _3, "hateblo": _3, "hatenablog": _3, "hatenadiary": _3, "2-d": _3, "bona": _3, "crap": _3, "daynight": _3, "eek": _3, "flop": _3, "halfmoon": _3, "jeez": _3, "matrix": _3, "mimoza": _3, "netgamers": _3, "nyanta": _3, "o0o0": _3, "rdy": _3, "rgr": _3, "rulez": _3, "sakurastorage": [0, { "isk01": _57, "isk02": _57 }], "saloon": _3, "sblo": _3, "skr": _3, "tank": _3, "uh-oh": _3, "undo": _3, "webaccel": [0, { "rs": _3, "user": _3 }], "websozai": _3, "xii": _3 }], "ke": [1, { "ac": _2, "co": _2, "go": _2, "info": _2, "me": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2 }], "kg": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "us": _3, "xx": _3 }], "kh": _18, "ki": _58, "km": [1, { "ass": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "nom": _2, "org": _2, "prd": _2, "tm": _2, "asso": _2, "coop": _2, "gouv": _2, "medecin": _2, "notaires": _2, "pharmaciens": _2, "presse": _2, "veterinaire": _2 }], "kn": [1, { "edu": _2, "gov": _2, "net": _2, "org": _2 }], "kp": [1, { "com": _2, "edu": _2, "gov": _2, "org": _2, "rep": _2, "tra": _2 }], "kr": [1, { "ac": _2, "ai": _2, "co": _2, "es": _2, "go": _2, "hs": _2, "io": _2, "it": _2, "kg": _2, "me": _2, "mil": _2, "ms": _2, "ne": _2, "or": _2, "pe": _2, "re": _2, "sc": _2, "busan": _2, "chungbuk": _2, "chungnam": _2, "daegu": _2, "daejeon": _2, "gangwon": _2, "gwangju": _2, "gyeongbuk": _2, "gyeonggi": _2, "gyeongnam": _2, "incheon": _2, "jeju": _2, "jeonbuk": _2, "jeonnam": _2, "seoul": _2, "ulsan": _2, "c01": _3, "eliv-cdn": _3, "eliv-dns": _3, "mmv": _3, "vki": _3 }], "kw": [1, { "com": _2, "edu": _2, "emb": _2, "gov": _2, "ind": _2, "net": _2, "org": _2 }], "ky": _45, "kz": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "jcloud": _3 }], "la": [1, { "com": _2, "edu": _2, "gov": _2, "info": _2, "int": _2, "net": _2, "org": _2, "per": _2, "bnr": _3 }], "lb": _4, "lc": [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "oy": _3 }], "li": _2, "lk": [1, { "ac": _2, "assn": _2, "com": _2, "edu": _2, "gov": _2, "grp": _2, "hotel": _2, "int": _2, "ltd": _2, "net": _2, "ngo": _2, "org": _2, "sch": _2, "soc": _2, "web": _2 }], "lr": _4, "ls": [1, { "ac": _2, "biz": _2, "co": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "sc": _2 }], "lt": _10, "lu": [1, { "123website": _3 }], "lv": [1, { "asn": _2, "com": _2, "conf": _2, "edu": _2, "gov": _2, "id": _2, "mil": _2, "net": _2, "org": _2 }], "ly": [1, { "com": _2, "edu": _2, "gov": _2, "id": _2, "med": _2, "net": _2, "org": _2, "plc": _2, "sch": _2 }], "ma": [1, { "ac": _2, "co": _2, "gov": _2, "net": _2, "org": _2, "press": _2 }], "mc": [1, { "asso": _2, "tm": _2 }], "md": [1, { "ir": _3 }], "me": [1, { "ac": _2, "co": _2, "edu": _2, "gov": _2, "its": _2, "net": _2, "org": _2, "priv": _2, "c66": _3, "craft": _3, "edgestack": _3, "filegear": _3, "filegear-sg": _3, "lohmus": _3, "barsy": _3, "mcdir": _3, "brasilia": _3, "ddns": _3, "dnsfor": _3, "hopto": _3, "loginto": _3, "noip": _3, "webhop": _3, "soundcast": _3, "tcp4": _3, "vp4": _3, "diskstation": _3, "dscloud": _3, "i234": _3, "myds": _3, "synology": _3, "transip": _44, "nohost": _3 }], "mg": [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "nom": _2, "org": _2, "prd": _2 }], "mh": _2, "mil": _2, "mk": [1, { "com": _2, "edu": _2, "gov": _2, "inf": _2, "name": _2, "net": _2, "org": _2 }], "ml": [1, { "ac": _2, "art": _2, "asso": _2, "com": _2, "edu": _2, "gouv": _2, "gov": _2, "info": _2, "inst": _2, "net": _2, "org": _2, "pr": _2, "presse": _2 }], "mm": _18, "mn": [1, { "edu": _2, "gov": _2, "org": _2, "nyc": _3 }], "mo": _4, "mobi": [1, { "barsy": _3, "dscloud": _3 }], "mp": [1, { "ju": _3 }], "mq": _2, "mr": _10, "ms": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "minisite": _3 }], "mt": _45, "mu": [1, { "ac": _2, "co": _2, "com": _2, "gov": _2, "net": _2, "or": _2, "org": _2 }], "museum": _2, "mv": [1, { "aero": _2, "biz": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "museum": _2, "name": _2, "net": _2, "org": _2, "pro": _2 }], "mw": [1, { "ac": _2, "biz": _2, "co": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "int": _2, "net": _2, "org": _2 }], "mx": [1, { "com": _2, "edu": _2, "gob": _2, "net": _2, "org": _2 }], "my": [1, { "biz": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2 }], "mz": [1, { "ac": _2, "adv": _2, "co": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 }], "na": [1, { "alt": _2, "co": _2, "com": _2, "gov": _2, "net": _2, "org": _2 }], "name": [1, { "her": _61, "his": _61 }], "nc": [1, { "asso": _2, "nom": _2 }], "ne": _2, "net": [1, { "adobeaemcloud": _3, "adobeio-static": _3, "adobeioruntime": _3, "akadns": _3, "akamai": _3, "akamai-staging": _3, "akamaiedge": _3, "akamaiedge-staging": _3, "akamaihd": _3, "akamaihd-staging": _3, "akamaiorigin": _3, "akamaiorigin-staging": _3, "akamaized": _3, "akamaized-staging": _3, "edgekey": _3, "edgekey-staging": _3, "edgesuite": _3, "edgesuite-staging": _3, "alwaysdata": _3, "myamaze": _3, "cloudfront": _3, "appudo": _3, "atlassian-dev": [0, { "prod": _53 }], "myfritz": _3, "onavstack": _3, "shopselect": _3, "blackbaudcdn": _3, "boomla": _3, "bplaced": _3, "square7": _3, "cdn77": [0, { "r": _3 }], "cdn77-ssl": _3, "gb": _3, "hu": _3, "jp": _3, "se": _3, "uk": _3, "clickrising": _3, "ddns-ip": _3, "dns-cloud": _3, "dns-dynamic": _3, "cloudaccess": _3, "cloudflare": [2, { "cdn": _3 }], "cloudflareanycast": _53, "cloudflarecn": _53, "cloudflareglobal": _53, "ctfcloud": _3, "feste-ip": _3, "knx-server": _3, "static-access": _3, "cryptonomic": _6, "dattolocal": _3, "mydatto": _3, "debian": _3, "definima": _3, "deno": _3, "icp": _6, "at-band-camp": _3, "blogdns": _3, "broke-it": _3, "buyshouses": _3, "dnsalias": _3, "dnsdojo": _3, "does-it": _3, "dontexist": _3, "dynalias": _3, "dynathome": _3, "endofinternet": _3, "from-az": _3, "from-co": _3, "from-la": _3, "from-ny": _3, "gets-it": _3, "ham-radio-op": _3, "homeftp": _3, "homeip": _3, "homelinux": _3, "homeunix": _3, "in-the-band": _3, "is-a-chef": _3, "is-a-geek": _3, "isa-geek": _3, "kicks-ass": _3, "office-on-the": _3, "podzone": _3, "scrapper-site": _3, "selfip": _3, "sells-it": _3, "servebbs": _3, "serveftp": _3, "thruhere": _3, "webhop": _3, "casacam": _3, "dynu": _3, "dynv6": _3, "twmail": _3, "ru": _3, "channelsdvr": [2, { "u": _3 }], "fastly": [0, { "freetls": _3, "map": _3, "prod": [0, { "a": _3, "global": _3 }], "ssl": [0, { "a": _3, "b": _3, "global": _3 }] }], "fastlylb": [2, { "map": _3 }], "edgeapp": _3, "keyword-on": _3, "live-on": _3, "server-on": _3, "cdn-edges": _3, "heteml": _3, "cloudfunctions": _3, "grafana-dev": _3, "iobb": _3, "moonscale": _3, "in-dsl": _3, "in-vpn": _3, "oninferno": _3, "botdash": _3, "apps-1and1": _3, "ipifony": _3, "cloudjiffy": [2, { "fra1-de": _3, "west1-us": _3 }], "elastx": [0, { "jls-sto1": _3, "jls-sto2": _3, "jls-sto3": _3 }], "massivegrid": [0, { "paas": [0, { "fr-1": _3, "lon-1": _3, "lon-2": _3, "ny-1": _3, "ny-2": _3, "sg-1": _3 }] }], "saveincloud": [0, { "jelastic": _3, "nordeste-idc": _3 }], "scaleforce": _46, "kinghost": _3, "uni5": _3, "krellian": _3, "ggff": _3, "localcert": _3, "localto": _6, "barsy": _3, "luyani": _3, "memset": _3, "azure-api": _3, "azure-mobile": _3, "azureedge": _3, "azurefd": _3, "azurestaticapps": [2, { "1": _3, "2": _3, "3": _3, "4": _3, "5": _3, "6": _3, "7": _3, "centralus": _3, "eastasia": _3, "eastus2": _3, "westeurope": _3, "westus2": _3 }], "azurewebsites": _3, "cloudapp": _3, "trafficmanager": _3, "windows": [0, { "core": [0, { "blob": _3 }], "servicebus": _3 }], "mynetname": [0, { "sn": _3 }], "routingthecloud": _3, "bounceme": _3, "ddns": _3, "eating-organic": _3, "mydissent": _3, "myeffect": _3, "mymediapc": _3, "mypsx": _3, "mysecuritycamera": _3, "nhlfan": _3, "no-ip": _3, "pgafan": _3, "privatizehealthinsurance": _3, "redirectme": _3, "serveblog": _3, "serveminecraft": _3, "sytes": _3, "dnsup": _3, "hicam": _3, "now-dns": _3, "ownip": _3, "vpndns": _3, "cloudycluster": _3, "ovh": [0, { "hosting": _6, "webpaas": _6 }], "rackmaze": _3, "myradweb": _3, "in": _3, "subsc-pay": _3, "squares": _3, "schokokeks": _3, "firewall-gateway": _3, "seidat": _3, "senseering": _3, "siteleaf": _3, "mafelo": _3, "myspreadshop": _3, "vps-host": [2, { "jelastic": [0, { "atl": _3, "njs": _3, "ric": _3 }] }], "srcf": [0, { "soc": _3, "user": _3 }], "supabase": _3, "dsmynas": _3, "familyds": _3, "ts": [2, { "c": _6 }], "torproject": [2, { "pages": _3 }], "vusercontent": _3, "reserve-online": _3, "community-pro": _3, "meinforum": _3, "yandexcloud": [2, { "storage": _3, "website": _3 }], "za": _3, "zabc": _3 }], "nf": [1, { "arts": _2, "com": _2, "firm": _2, "info": _2, "net": _2, "other": _2, "per": _2, "rec": _2, "store": _2, "web": _2 }], "ng": [1, { "com": _2, "edu": _2, "gov": _2, "i": _2, "mil": _2, "mobi": _2, "name": _2, "net": _2, "org": _2, "sch": _2, "biz": [2, { "co": _3, "dl": _3, "go": _3, "lg": _3, "on": _3 }], "col": _3, "firm": _3, "gen": _3, "ltd": _3, "ngo": _3, "plc": _3 }], "ni": [1, { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gob": _2, "in": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "web": _2 }], "nl": [1, { "co": _3, "hosting-cluster": _3, "gov": _3, "khplay": _3, "123website": _3, "myspreadshop": _3, "transurl": _6, "cistron": _3, "demon": _3 }], "no": [1, { "fhs": _2, "folkebibl": _2, "fylkesbibl": _2, "idrett": _2, "museum": _2, "priv": _2, "vgs": _2, "dep": _2, "herad": _2, "kommune": _2, "mil": _2, "stat": _2, "aa": _62, "ah": _62, "bu": _62, "fm": _62, "hl": _62, "hm": _62, "jan-mayen": _62, "mr": _62, "nl": _62, "nt": _62, "of": _62, "ol": _62, "oslo": _62, "rl": _62, "sf": _62, "st": _62, "svalbard": _62, "tm": _62, "tr": _62, "va": _62, "vf": _62, "akrehamn": _2, "xn--krehamn-dxa": _2, "åkrehamn": _2, "algard": _2, "xn--lgrd-poac": _2, "ålgård": _2, "arna": _2, "bronnoysund": _2, "xn--brnnysund-m8ac": _2, "brønnøysund": _2, "brumunddal": _2, "bryne": _2, "drobak": _2, "xn--drbak-wua": _2, "drøbak": _2, "egersund": _2, "fetsund": _2, "floro": _2, "xn--flor-jra": _2, "florø": _2, "fredrikstad": _2, "hokksund": _2, "honefoss": _2, "xn--hnefoss-q1a": _2, "hønefoss": _2, "jessheim": _2, "jorpeland": _2, "xn--jrpeland-54a": _2, "jørpeland": _2, "kirkenes": _2, "kopervik": _2, "krokstadelva": _2, "langevag": _2, "xn--langevg-jxa": _2, "langevåg": _2, "leirvik": _2, "mjondalen": _2, "xn--mjndalen-64a": _2, "mjøndalen": _2, "mo-i-rana": _2, "mosjoen": _2, "xn--mosjen-eya": _2, "mosjøen": _2, "nesoddtangen": _2, "orkanger": _2, "osoyro": _2, "xn--osyro-wua": _2, "osøyro": _2, "raholt": _2, "xn--rholt-mra": _2, "råholt": _2, "sandnessjoen": _2, "xn--sandnessjen-ogb": _2, "sandnessjøen": _2, "skedsmokorset": _2, "slattum": _2, "spjelkavik": _2, "stathelle": _2, "stavern": _2, "stjordalshalsen": _2, "xn--stjrdalshalsen-sqb": _2, "stjørdalshalsen": _2, "tananger": _2, "tranby": _2, "vossevangen": _2, "aarborte": _2, "aejrie": _2, "afjord": _2, "xn--fjord-lra": _2, "åfjord": _2, "agdenes": _2, "akershus": _63, "aknoluokta": _2, "xn--koluokta-7ya57h": _2, "ákŋoluokta": _2, "al": _2, "xn--l-1fa": _2, "ål": _2, "alaheadju": _2, "xn--laheadju-7ya": _2, "álaheadju": _2, "alesund": _2, "xn--lesund-hua": _2, "ålesund": _2, "alstahaug": _2, "alta": _2, "xn--lt-liac": _2, "áltá": _2, "alvdal": _2, "amli": _2, "xn--mli-tla": _2, "åmli": _2, "amot": _2, "xn--mot-tla": _2, "åmot": _2, "andasuolo": _2, "andebu": _2, "andoy": _2, "xn--andy-ira": _2, "andøy": _2, "ardal": _2, "xn--rdal-poa": _2, "årdal": _2, "aremark": _2, "arendal": _2, "xn--s-1fa": _2, "ås": _2, "aseral": _2, "xn--seral-lra": _2, "åseral": _2, "asker": _2, "askim": _2, "askoy": _2, "xn--asky-ira": _2, "askøy": _2, "askvoll": _2, "asnes": _2, "xn--snes-poa": _2, "åsnes": _2, "audnedaln": _2, "aukra": _2, "aure": _2, "aurland": _2, "aurskog-holand": _2, "xn--aurskog-hland-jnb": _2, "aurskog-høland": _2, "austevoll": _2, "austrheim": _2, "averoy": _2, "xn--avery-yua": _2, "averøy": _2, "badaddja": _2, "xn--bdddj-mrabd": _2, "bådåddjå": _2, "xn--brum-voa": _2, "bærum": _2, "bahcavuotna": _2, "xn--bhcavuotna-s4a": _2, "báhcavuotna": _2, "bahccavuotna": _2, "xn--bhccavuotna-k7a": _2, "báhccavuotna": _2, "baidar": _2, "xn--bidr-5nac": _2, "báidár": _2, "bajddar": _2, "xn--bjddar-pta": _2, "bájddar": _2, "balat": _2, "xn--blt-elab": _2, "bálát": _2, "balestrand": _2, "ballangen": _2, "balsfjord": _2, "bamble": _2, "bardu": _2, "barum": _2, "batsfjord": _2, "xn--btsfjord-9za": _2, "båtsfjord": _2, "bearalvahki": _2, "xn--bearalvhki-y4a": _2, "bearalváhki": _2, "beardu": _2, "beiarn": _2, "berg": _2, "bergen": _2, "berlevag": _2, "xn--berlevg-jxa": _2, "berlevåg": _2, "bievat": _2, "xn--bievt-0qa": _2, "bievát": _2, "bindal": _2, "birkenes": _2, "bjarkoy": _2, "xn--bjarky-fya": _2, "bjarkøy": _2, "bjerkreim": _2, "bjugn": _2, "bodo": _2, "xn--bod-2na": _2, "bodø": _2, "bokn": _2, "bomlo": _2, "xn--bmlo-gra": _2, "bømlo": _2, "bremanger": _2, "bronnoy": _2, "xn--brnny-wuac": _2, "brønnøy": _2, "budejju": _2, "buskerud": _63, "bygland": _2, "bykle": _2, "cahcesuolo": _2, "xn--hcesuolo-7ya35b": _2, "čáhcesuolo": _2, "davvenjarga": _2, "xn--davvenjrga-y4a": _2, "davvenjárga": _2, "davvesiida": _2, "deatnu": _2, "dielddanuorri": _2, "divtasvuodna": _2, "divttasvuotna": _2, "donna": _2, "xn--dnna-gra": _2, "dønna": _2, "dovre": _2, "drammen": _2, "drangedal": _2, "dyroy": _2, "xn--dyry-ira": _2, "dyrøy": _2, "eid": _2, "eidfjord": _2, "eidsberg": _2, "eidskog": _2, "eidsvoll": _2, "eigersund": _2, "elverum": _2, "enebakk": _2, "engerdal": _2, "etne": _2, "etnedal": _2, "evenassi": _2, "xn--eveni-0qa01ga": _2, "evenášši": _2, "evenes": _2, "evje-og-hornnes": _2, "farsund": _2, "fauske": _2, "fedje": _2, "fet": _2, "finnoy": _2, "xn--finny-yua": _2, "finnøy": _2, "fitjar": _2, "fjaler": _2, "fjell": _2, "fla": _2, "xn--fl-zia": _2, "flå": _2, "flakstad": _2, "flatanger": _2, "flekkefjord": _2, "flesberg": _2, "flora": _2, "folldal": _2, "forde": _2, "xn--frde-gra": _2, "førde": _2, "forsand": _2, "fosnes": _2, "xn--frna-woa": _2, "fræna": _2, "frana": _2, "frei": _2, "frogn": _2, "froland": _2, "frosta": _2, "froya": _2, "xn--frya-hra": _2, "frøya": _2, "fuoisku": _2, "fuossko": _2, "fusa": _2, "fyresdal": _2, "gaivuotna": _2, "xn--givuotna-8ya": _2, "gáivuotna": _2, "galsa": _2, "xn--gls-elac": _2, "gálsá": _2, "gamvik": _2, "gangaviika": _2, "xn--ggaviika-8ya47h": _2, "gáŋgaviika": _2, "gaular": _2, "gausdal": _2, "giehtavuoatna": _2, "gildeskal": _2, "xn--gildeskl-g0a": _2, "gildeskål": _2, "giske": _2, "gjemnes": _2, "gjerdrum": _2, "gjerstad": _2, "gjesdal": _2, "gjovik": _2, "xn--gjvik-wua": _2, "gjøvik": _2, "gloppen": _2, "gol": _2, "gran": _2, "grane": _2, "granvin": _2, "gratangen": _2, "grimstad": _2, "grong": _2, "grue": _2, "gulen": _2, "guovdageaidnu": _2, "ha": _2, "xn--h-2fa": _2, "hå": _2, "habmer": _2, "xn--hbmer-xqa": _2, "hábmer": _2, "hadsel": _2, "xn--hgebostad-g3a": _2, "hægebostad": _2, "hagebostad": _2, "halden": _2, "halsa": _2, "hamar": _2, "hamaroy": _2, "hammarfeasta": _2, "xn--hmmrfeasta-s4ac": _2, "hámmárfeasta": _2, "hammerfest": _2, "hapmir": _2, "xn--hpmir-xqa": _2, "hápmir": _2, "haram": _2, "hareid": _2, "harstad": _2, "hasvik": _2, "hattfjelldal": _2, "haugesund": _2, "hedmark": [0, { "os": _2, "valer": _2, "xn--vler-qoa": _2, "våler": _2 }], "hemne": _2, "hemnes": _2, "hemsedal": _2, "hitra": _2, "hjartdal": _2, "hjelmeland": _2, "hobol": _2, "xn--hobl-ira": _2, "hobøl": _2, "hof": _2, "hol": _2, "hole": _2, "holmestrand": _2, "holtalen": _2, "xn--holtlen-hxa": _2, "holtålen": _2, "hordaland": [0, { "os": _2 }], "hornindal": _2, "horten": _2, "hoyanger": _2, "xn--hyanger-q1a": _2, "høyanger": _2, "hoylandet": _2, "xn--hylandet-54a": _2, "høylandet": _2, "hurdal": _2, "hurum": _2, "hvaler": _2, "hyllestad": _2, "ibestad": _2, "inderoy": _2, "xn--indery-fya": _2, "inderøy": _2, "iveland": _2, "ivgu": _2, "jevnaker": _2, "jolster": _2, "xn--jlster-bya": _2, "jølster": _2, "jondal": _2, "kafjord": _2, "xn--kfjord-iua": _2, "kåfjord": _2, "karasjohka": _2, "xn--krjohka-hwab49j": _2, "kárášjohka": _2, "karasjok": _2, "karlsoy": _2, "karmoy": _2, "xn--karmy-yua": _2, "karmøy": _2, "kautokeino": _2, "klabu": _2, "xn--klbu-woa": _2, "klæbu": _2, "klepp": _2, "kongsberg": _2, "kongsvinger": _2, "kraanghke": _2, "xn--kranghke-b0a": _2, "kråanghke": _2, "kragero": _2, "xn--krager-gya": _2, "kragerø": _2, "kristiansand": _2, "kristiansund": _2, "krodsherad": _2, "xn--krdsherad-m8a": _2, "krødsherad": _2, "xn--kvfjord-nxa": _2, "kvæfjord": _2, "xn--kvnangen-k0a": _2, "kvænangen": _2, "kvafjord": _2, "kvalsund": _2, "kvam": _2, "kvanangen": _2, "kvinesdal": _2, "kvinnherad": _2, "kviteseid": _2, "kvitsoy": _2, "xn--kvitsy-fya": _2, "kvitsøy": _2, "laakesvuemie": _2, "xn--lrdal-sra": _2, "lærdal": _2, "lahppi": _2, "xn--lhppi-xqa": _2, "láhppi": _2, "lardal": _2, "larvik": _2, "lavagis": _2, "lavangen": _2, "leangaviika": _2, "xn--leagaviika-52b": _2, "leaŋgaviika": _2, "lebesby": _2, "leikanger": _2, "leirfjord": _2, "leka": _2, "leksvik": _2, "lenvik": _2, "lerdal": _2, "lesja": _2, "levanger": _2, "lier": _2, "lierne": _2, "lillehammer": _2, "lillesand": _2, "lindas": _2, "xn--linds-pra": _2, "lindås": _2, "lindesnes": _2, "loabat": _2, "xn--loabt-0qa": _2, "loabát": _2, "lodingen": _2, "xn--ldingen-q1a": _2, "lødingen": _2, "lom": _2, "loppa": _2, "lorenskog": _2, "xn--lrenskog-54a": _2, "lørenskog": _2, "loten": _2, "xn--lten-gra": _2, "løten": _2, "lund": _2, "lunner": _2, "luroy": _2, "xn--lury-ira": _2, "lurøy": _2, "luster": _2, "lyngdal": _2, "lyngen": _2, "malatvuopmi": _2, "xn--mlatvuopmi-s4a": _2, "málatvuopmi": _2, "malselv": _2, "xn--mlselv-iua": _2, "målselv": _2, "malvik": _2, "mandal": _2, "marker": _2, "marnardal": _2, "masfjorden": _2, "masoy": _2, "xn--msy-ula0h": _2, "måsøy": _2, "matta-varjjat": _2, "xn--mtta-vrjjat-k7af": _2, "mátta-várjjat": _2, "meland": _2, "meldal": _2, "melhus": _2, "meloy": _2, "xn--mely-ira": _2, "meløy": _2, "meraker": _2, "xn--merker-kua": _2, "meråker": _2, "midsund": _2, "midtre-gauldal": _2, "moareke": _2, "xn--moreke-jua": _2, "moåreke": _2, "modalen": _2, "modum": _2, "molde": _2, "more-og-romsdal": [0, { "heroy": _2, "sande": _2 }], "xn--mre-og-romsdal-qqb": [0, { "xn--hery-ira": _2, "sande": _2 }], "møre-og-romsdal": [0, { "herøy": _2, "sande": _2 }], "moskenes": _2, "moss": _2, "mosvik": _2, "muosat": _2, "xn--muost-0qa": _2, "muosát": _2, "naamesjevuemie": _2, "xn--nmesjevuemie-tcba": _2, "nååmesjevuemie": _2, "xn--nry-yla5g": _2, "nærøy": _2, "namdalseid": _2, "namsos": _2, "namsskogan": _2, "nannestad": _2, "naroy": _2, "narviika": _2, "narvik": _2, "naustdal": _2, "navuotna": _2, "xn--nvuotna-hwa": _2, "návuotna": _2, "nedre-eiker": _2, "nesna": _2, "nesodden": _2, "nesseby": _2, "nesset": _2, "nissedal": _2, "nittedal": _2, "nord-aurdal": _2, "nord-fron": _2, "nord-odal": _2, "norddal": _2, "nordkapp": _2, "nordland": [0, { "bo": _2, "xn--b-5ga": _2, "bø": _2, "heroy": _2, "xn--hery-ira": _2, "herøy": _2 }], "nordre-land": _2, "nordreisa": _2, "nore-og-uvdal": _2, "notodden": _2, "notteroy": _2, "xn--nttery-byae": _2, "nøtterøy": _2, "odda": _2, "oksnes": _2, "xn--ksnes-uua": _2, "øksnes": _2, "omasvuotna": _2, "oppdal": _2, "oppegard": _2, "xn--oppegrd-ixa": _2, "oppegård": _2, "orkdal": _2, "orland": _2, "xn--rland-uua": _2, "ørland": _2, "orskog": _2, "xn--rskog-uua": _2, "ørskog": _2, "orsta": _2, "xn--rsta-fra": _2, "ørsta": _2, "osen": _2, "osteroy": _2, "xn--ostery-fya": _2, "osterøy": _2, "ostfold": [0, { "valer": _2 }], "xn--stfold-9xa": [0, { "xn--vler-qoa": _2 }], "østfold": [0, { "våler": _2 }], "ostre-toten": _2, "xn--stre-toten-zcb": _2, "østre-toten": _2, "overhalla": _2, "ovre-eiker": _2, "xn--vre-eiker-k8a": _2, "øvre-eiker": _2, "oyer": _2, "xn--yer-zna": _2, "øyer": _2, "oygarden": _2, "xn--ygarden-p1a": _2, "øygarden": _2, "oystre-slidre": _2, "xn--ystre-slidre-ujb": _2, "øystre-slidre": _2, "porsanger": _2, "porsangu": _2, "xn--porsgu-sta26f": _2, "porsáŋgu": _2, "porsgrunn": _2, "rade": _2, "xn--rde-ula": _2, "råde": _2, "radoy": _2, "xn--rady-ira": _2, "radøy": _2, "xn--rlingen-mxa": _2, "rælingen": _2, "rahkkeravju": _2, "xn--rhkkervju-01af": _2, "ráhkkerávju": _2, "raisa": _2, "xn--risa-5na": _2, "ráisa": _2, "rakkestad": _2, "ralingen": _2, "rana": _2, "randaberg": _2, "rauma": _2, "rendalen": _2, "rennebu": _2, "rennesoy": _2, "xn--rennesy-v1a": _2, "rennesøy": _2, "rindal": _2, "ringebu": _2, "ringerike": _2, "ringsaker": _2, "risor": _2, "xn--risr-ira": _2, "risør": _2, "rissa": _2, "roan": _2, "rodoy": _2, "xn--rdy-0nab": _2, "rødøy": _2, "rollag": _2, "romsa": _2, "romskog": _2, "xn--rmskog-bya": _2, "rømskog": _2, "roros": _2, "xn--rros-gra": _2, "røros": _2, "rost": _2, "xn--rst-0na": _2, "røst": _2, "royken": _2, "xn--ryken-vua": _2, "røyken": _2, "royrvik": _2, "xn--ryrvik-bya": _2, "røyrvik": _2, "ruovat": _2, "rygge": _2, "salangen": _2, "salat": _2, "xn--slat-5na": _2, "sálat": _2, "xn--slt-elab": _2, "sálát": _2, "saltdal": _2, "samnanger": _2, "sandefjord": _2, "sandnes": _2, "sandoy": _2, "xn--sandy-yua": _2, "sandøy": _2, "sarpsborg": _2, "sauda": _2, "sauherad": _2, "sel": _2, "selbu": _2, "selje": _2, "seljord": _2, "siellak": _2, "sigdal": _2, "siljan": _2, "sirdal": _2, "skanit": _2, "xn--sknit-yqa": _2, "skánit": _2, "skanland": _2, "xn--sknland-fxa": _2, "skånland": _2, "skaun": _2, "skedsmo": _2, "ski": _2, "skien": _2, "skierva": _2, "xn--skierv-uta": _2, "skiervá": _2, "skiptvet": _2, "skjak": _2, "xn--skjk-soa": _2, "skjåk": _2, "skjervoy": _2, "xn--skjervy-v1a": _2, "skjervøy": _2, "skodje": _2, "smola": _2, "xn--smla-hra": _2, "smøla": _2, "snaase": _2, "xn--snase-nra": _2, "snåase": _2, "snasa": _2, "xn--snsa-roa": _2, "snåsa": _2, "snillfjord": _2, "snoasa": _2, "sogndal": _2, "sogne": _2, "xn--sgne-gra": _2, "søgne": _2, "sokndal": _2, "sola": _2, "solund": _2, "somna": _2, "xn--smna-gra": _2, "sømna": _2, "sondre-land": _2, "xn--sndre-land-0cb": _2, "søndre-land": _2, "songdalen": _2, "sor-aurdal": _2, "xn--sr-aurdal-l8a": _2, "sør-aurdal": _2, "sor-fron": _2, "xn--sr-fron-q1a": _2, "sør-fron": _2, "sor-odal": _2, "xn--sr-odal-q1a": _2, "sør-odal": _2, "sor-varanger": _2, "xn--sr-varanger-ggb": _2, "sør-varanger": _2, "sorfold": _2, "xn--srfold-bya": _2, "sørfold": _2, "sorreisa": _2, "xn--srreisa-q1a": _2, "sørreisa": _2, "sortland": _2, "sorum": _2, "xn--srum-gra": _2, "sørum": _2, "spydeberg": _2, "stange": _2, "stavanger": _2, "steigen": _2, "steinkjer": _2, "stjordal": _2, "xn--stjrdal-s1a": _2, "stjørdal": _2, "stokke": _2, "stor-elvdal": _2, "stord": _2, "stordal": _2, "storfjord": _2, "strand": _2, "stranda": _2, "stryn": _2, "sula": _2, "suldal": _2, "sund": _2, "sunndal": _2, "surnadal": _2, "sveio": _2, "svelvik": _2, "sykkylven": _2, "tana": _2, "telemark": [0, { "bo": _2, "xn--b-5ga": _2, "bø": _2 }], "time": _2, "tingvoll": _2, "tinn": _2, "tjeldsund": _2, "tjome": _2, "xn--tjme-hra": _2, "tjøme": _2, "tokke": _2, "tolga": _2, "tonsberg": _2, "xn--tnsberg-q1a": _2, "tønsberg": _2, "torsken": _2, "xn--trna-woa": _2, "træna": _2, "trana": _2, "tranoy": _2, "xn--trany-yua": _2, "tranøy": _2, "troandin": _2, "trogstad": _2, "xn--trgstad-r1a": _2, "trøgstad": _2, "tromsa": _2, "tromso": _2, "xn--troms-zua": _2, "tromsø": _2, "trondheim": _2, "trysil": _2, "tvedestrand": _2, "tydal": _2, "tynset": _2, "tysfjord": _2, "tysnes": _2, "xn--tysvr-vra": _2, "tysvær": _2, "tysvar": _2, "ullensaker": _2, "ullensvang": _2, "ulvik": _2, "unjarga": _2, "xn--unjrga-rta": _2, "unjárga": _2, "utsira": _2, "vaapste": _2, "vadso": _2, "xn--vads-jra": _2, "vadsø": _2, "xn--vry-yla5g": _2, "værøy": _2, "vaga": _2, "xn--vg-yiab": _2, "vågå": _2, "vagan": _2, "xn--vgan-qoa": _2, "vågan": _2, "vagsoy": _2, "xn--vgsy-qoa0j": _2, "vågsøy": _2, "vaksdal": _2, "valle": _2, "vang": _2, "vanylven": _2, "vardo": _2, "xn--vard-jra": _2, "vardø": _2, "varggat": _2, "xn--vrggt-xqad": _2, "várggát": _2, "varoy": _2, "vefsn": _2, "vega": _2, "vegarshei": _2, "xn--vegrshei-c0a": _2, "vegårshei": _2, "vennesla": _2, "verdal": _2, "verran": _2, "vestby": _2, "vestfold": [0, { "sande": _2 }], "vestnes": _2, "vestre-slidre": _2, "vestre-toten": _2, "vestvagoy": _2, "xn--vestvgy-ixa6o": _2, "vestvågøy": _2, "vevelstad": _2, "vik": _2, "vikna": _2, "vindafjord": _2, "voagat": _2, "volda": _2, "voss": _2, "co": _3, "123hjemmeside": _3, "myspreadshop": _3 }], "np": _18, "nr": _58, "nu": [1, { "merseine": _3, "mine": _3, "shacknet": _3, "enterprisecloud": _3 }], "nz": [1, { "ac": _2, "co": _2, "cri": _2, "geek": _2, "gen": _2, "govt": _2, "health": _2, "iwi": _2, "kiwi": _2, "maori": _2, "xn--mori-qsa": _2, "māori": _2, "mil": _2, "net": _2, "org": _2, "parliament": _2, "school": _2, "cloudns": _3 }], "om": [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "med": _2, "museum": _2, "net": _2, "org": _2, "pro": _2 }], "onion": _2, "org": [1, { "altervista": _3, "pimienta": _3, "poivron": _3, "potager": _3, "sweetpepper": _3, "cdn77": [0, { "c": _3, "rsc": _3 }], "cdn77-secure": [0, { "origin": [0, { "ssl": _3 }] }], "ae": _3, "cloudns": _3, "ip-dynamic": _3, "ddnss": _3, "dpdns": _3, "duckdns": _3, "tunk": _3, "blogdns": _3, "blogsite": _3, "boldlygoingnowhere": _3, "dnsalias": _3, "dnsdojo": _3, "doesntexist": _3, "dontexist": _3, "doomdns": _3, "dvrdns": _3, "dynalias": _3, "dyndns": [2, { "go": _3, "home": _3 }], "endofinternet": _3, "endoftheinternet": _3, "from-me": _3, "game-host": _3, "gotdns": _3, "hobby-site": _3, "homedns": _3, "homeftp": _3, "homelinux": _3, "homeunix": _3, "is-a-bruinsfan": _3, "is-a-candidate": _3, "is-a-celticsfan": _3, "is-a-chef": _3, "is-a-geek": _3, "is-a-knight": _3, "is-a-linux-user": _3, "is-a-patsfan": _3, "is-a-soxfan": _3, "is-found": _3, "is-lost": _3, "is-saved": _3, "is-very-bad": _3, "is-very-evil": _3, "is-very-good": _3, "is-very-nice": _3, "is-very-sweet": _3, "isa-geek": _3, "kicks-ass": _3, "misconfused": _3, "podzone": _3, "readmyblog": _3, "selfip": _3, "sellsyourhome": _3, "servebbs": _3, "serveftp": _3, "servegame": _3, "stuff-4-sale": _3, "webhop": _3, "accesscam": _3, "camdvr": _3, "freeddns": _3, "mywire": _3, "webredirect": _3, "twmail": _3, "eu": [2, { "al": _3, "asso": _3, "at": _3, "au": _3, "be": _3, "bg": _3, "ca": _3, "cd": _3, "ch": _3, "cn": _3, "cy": _3, "cz": _3, "de": _3, "dk": _3, "edu": _3, "ee": _3, "es": _3, "fi": _3, "fr": _3, "gr": _3, "hr": _3, "hu": _3, "ie": _3, "il": _3, "in": _3, "int": _3, "is": _3, "it": _3, "jp": _3, "kr": _3, "lt": _3, "lu": _3, "lv": _3, "me": _3, "mk": _3, "mt": _3, "my": _3, "net": _3, "ng": _3, "nl": _3, "no": _3, "nz": _3, "pl": _3, "pt": _3, "ro": _3, "ru": _3, "se": _3, "si": _3, "sk": _3, "tr": _3, "uk": _3, "us": _3 }], "fedorainfracloud": _3, "fedorapeople": _3, "fedoraproject": [0, { "cloud": _3, "os": _43, "stg": [0, { "os": _43 }] }], "freedesktop": _3, "hatenadiary": _3, "hepforge": _3, "in-dsl": _3, "in-vpn": _3, "js": _3, "barsy": _3, "mayfirst": _3, "routingthecloud": _3, "bmoattachments": _3, "cable-modem": _3, "collegefan": _3, "couchpotatofries": _3, "hopto": _3, "mlbfan": _3, "myftp": _3, "mysecuritycamera": _3, "nflfan": _3, "no-ip": _3, "read-books": _3, "ufcfan": _3, "zapto": _3, "dynserv": _3, "now-dns": _3, "is-local": _3, "httpbin": _3, "pubtls": _3, "jpn": _3, "my-firewall": _3, "myfirewall": _3, "spdns": _3, "small-web": _3, "dsmynas": _3, "familyds": _3, "teckids": _57, "tuxfamily": _3, "diskstation": _3, "hk": _3, "us": _3, "toolforge": _3, "wmcloud": [2, { "beta": _3 }], "wmflabs": _3, "za": _3 }], "pa": [1, { "abo": _2, "ac": _2, "com": _2, "edu": _2, "gob": _2, "ing": _2, "med": _2, "net": _2, "nom": _2, "org": _2, "sld": _2 }], "pe": [1, { "com": _2, "edu": _2, "gob": _2, "mil": _2, "net": _2, "nom": _2, "org": _2 }], "pf": [1, { "com": _2, "edu": _2, "org": _2 }], "pg": _18, "ph": [1, { "com": _2, "edu": _2, "gov": _2, "i": _2, "mil": _2, "net": _2, "ngo": _2, "org": _2, "cloudns": _3 }], "pk": [1, { "ac": _2, "biz": _2, "com": _2, "edu": _2, "fam": _2, "gkp": _2, "gob": _2, "gog": _2, "gok": _2, "gop": _2, "gos": _2, "gov": _2, "net": _2, "org": _2, "web": _2 }], "pl": [1, { "com": _2, "net": _2, "org": _2, "agro": _2, "aid": _2, "atm": _2, "auto": _2, "biz": _2, "edu": _2, "gmina": _2, "gsm": _2, "info": _2, "mail": _2, "media": _2, "miasta": _2, "mil": _2, "nieruchomosci": _2, "nom": _2, "pc": _2, "powiat": _2, "priv": _2, "realestate": _2, "rel": _2, "sex": _2, "shop": _2, "sklep": _2, "sos": _2, "szkola": _2, "targi": _2, "tm": _2, "tourism": _2, "travel": _2, "turystyka": _2, "gov": [1, { "ap": _2, "griw": _2, "ic": _2, "is": _2, "kmpsp": _2, "konsulat": _2, "kppsp": _2, "kwp": _2, "kwpsp": _2, "mup": _2, "mw": _2, "oia": _2, "oirm": _2, "oke": _2, "oow": _2, "oschr": _2, "oum": _2, "pa": _2, "pinb": _2, "piw": _2, "po": _2, "pr": _2, "psp": _2, "psse": _2, "pup": _2, "rzgw": _2, "sa": _2, "sdn": _2, "sko": _2, "so": _2, "sr": _2, "starostwo": _2, "ug": _2, "ugim": _2, "um": _2, "umig": _2, "upow": _2, "uppo": _2, "us": _2, "uw": _2, "uzs": _2, "wif": _2, "wiih": _2, "winb": _2, "wios": _2, "witd": _2, "wiw": _2, "wkz": _2, "wsa": _2, "wskr": _2, "wsse": _2, "wuoz": _2, "wzmiuw": _2, "zp": _2, "zpisdn": _2 }], "augustow": _2, "babia-gora": _2, "bedzin": _2, "beskidy": _2, "bialowieza": _2, "bialystok": _2, "bielawa": _2, "bieszczady": _2, "boleslawiec": _2, "bydgoszcz": _2, "bytom": _2, "cieszyn": _2, "czeladz": _2, "czest": _2, "dlugoleka": _2, "elblag": _2, "elk": _2, "glogow": _2, "gniezno": _2, "gorlice": _2, "grajewo": _2, "ilawa": _2, "jaworzno": _2, "jelenia-gora": _2, "jgora": _2, "kalisz": _2, "karpacz": _2, "kartuzy": _2, "kaszuby": _2, "katowice": _2, "kazimierz-dolny": _2, "kepno": _2, "ketrzyn": _2, "klodzko": _2, "kobierzyce": _2, "kolobrzeg": _2, "konin": _2, "konskowola": _2, "kutno": _2, "lapy": _2, "lebork": _2, "legnica": _2, "lezajsk": _2, "limanowa": _2, "lomza": _2, "lowicz": _2, "lubin": _2, "lukow": _2, "malbork": _2, "malopolska": _2, "mazowsze": _2, "mazury": _2, "mielec": _2, "mielno": _2, "mragowo": _2, "naklo": _2, "nowaruda": _2, "nysa": _2, "olawa": _2, "olecko": _2, "olkusz": _2, "olsztyn": _2, "opoczno": _2, "opole": _2, "ostroda": _2, "ostroleka": _2, "ostrowiec": _2, "ostrowwlkp": _2, "pila": _2, "pisz": _2, "podhale": _2, "podlasie": _2, "polkowice": _2, "pomorskie": _2, "pomorze": _2, "prochowice": _2, "pruszkow": _2, "przeworsk": _2, "pulawy": _2, "radom": _2, "rawa-maz": _2, "rybnik": _2, "rzeszow": _2, "sanok": _2, "sejny": _2, "skoczow": _2, "slask": _2, "slupsk": _2, "sosnowiec": _2, "stalowa-wola": _2, "starachowice": _2, "stargard": _2, "suwalki": _2, "swidnica": _2, "swiebodzin": _2, "swinoujscie": _2, "szczecin": _2, "szczytno": _2, "tarnobrzeg": _2, "tgory": _2, "turek": _2, "tychy": _2, "ustka": _2, "walbrzych": _2, "warmia": _2, "warszawa": _2, "waw": _2, "wegrow": _2, "wielun": _2, "wlocl": _2, "wloclawek": _2, "wodzislaw": _2, "wolomin": _2, "wroclaw": _2, "zachpomor": _2, "zagan": _2, "zarow": _2, "zgora": _2, "zgorzelec": _2, "art": _3, "gliwice": _3, "krakow": _3, "poznan": _3, "wroc": _3, "zakopane": _3, "beep": _3, "ecommerce-shop": _3, "cfolks": _3, "dfirma": _3, "dkonto": _3, "you2": _3, "shoparena": _3, "homesklep": _3, "sdscloud": _3, "unicloud": _3, "lodz": _3, "pabianice": _3, "plock": _3, "sieradz": _3, "skierniewice": _3, "zgierz": _3, "krasnik": _3, "leczna": _3, "lubartow": _3, "lublin": _3, "poniatowa": _3, "swidnik": _3, "co": _3, "torun": _3, "simplesite": _3, "myspreadshop": _3, "gda": _3, "gdansk": _3, "gdynia": _3, "med": _3, "sopot": _3, "bielsko": _3 }], "pm": [1, { "own": _3, "name": _3 }], "pn": [1, { "co": _2, "edu": _2, "gov": _2, "net": _2, "org": _2 }], "post": _2, "pr": [1, { "biz": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "isla": _2, "name": _2, "net": _2, "org": _2, "pro": _2, "ac": _2, "est": _2, "prof": _2 }], "pro": [1, { "aaa": _2, "aca": _2, "acct": _2, "avocat": _2, "bar": _2, "cpa": _2, "eng": _2, "jur": _2, "law": _2, "med": _2, "recht": _2, "12chars": _3, "cloudns": _3, "barsy": _3, "ngrok": _3 }], "ps": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "plo": _2, "sec": _2 }], "pt": [1, { "com": _2, "edu": _2, "gov": _2, "int": _2, "net": _2, "nome": _2, "org": _2, "publ": _2, "123paginaweb": _3 }], "pw": [1, { "gov": _2, "cloudns": _3, "x443": _3 }], "py": [1, { "com": _2, "coop": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 }], "qa": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sch": _2 }], "re": [1, { "asso": _2, "com": _2, "netlib": _3, "can": _3 }], "ro": [1, { "arts": _2, "com": _2, "firm": _2, "info": _2, "nom": _2, "nt": _2, "org": _2, "rec": _2, "store": _2, "tm": _2, "www": _2, "co": _3, "shop": _3, "barsy": _3 }], "rs": [1, { "ac": _2, "co": _2, "edu": _2, "gov": _2, "in": _2, "org": _2, "brendly": _52, "barsy": _3, "ox": _3 }], "ru": [1, { "ac": _3, "edu": _3, "gov": _3, "int": _3, "mil": _3, "eurodir": _3, "adygeya": _3, "bashkiria": _3, "bir": _3, "cbg": _3, "com": _3, "dagestan": _3, "grozny": _3, "kalmykia": _3, "kustanai": _3, "marine": _3, "mordovia": _3, "msk": _3, "mytis": _3, "nalchik": _3, "nov": _3, "pyatigorsk": _3, "spb": _3, "vladikavkaz": _3, "vladimir": _3, "na4u": _3, "mircloud": _3, "myjino": [2, { "hosting": _6, "landing": _6, "spectrum": _6, "vps": _6 }], "cldmail": [0, { "hb": _3 }], "mcdir": [2, { "vps": _3 }], "mcpre": _3, "net": _3, "org": _3, "pp": _3, "lk3": _3, "ras": _3 }], "rw": [1, { "ac": _2, "co": _2, "coop": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 }], "sa": [1, { "com": _2, "edu": _2, "gov": _2, "med": _2, "net": _2, "org": _2, "pub": _2, "sch": _2 }], "sb": _4, "sc": _4, "sd": [1, { "com": _2, "edu": _2, "gov": _2, "info": _2, "med": _2, "net": _2, "org": _2, "tv": _2 }], "se": [1, { "a": _2, "ac": _2, "b": _2, "bd": _2, "brand": _2, "c": _2, "d": _2, "e": _2, "f": _2, "fh": _2, "fhsk": _2, "fhv": _2, "g": _2, "h": _2, "i": _2, "k": _2, "komforb": _2, "kommunalforbund": _2, "komvux": _2, "l": _2, "lanbib": _2, "m": _2, "n": _2, "naturbruksgymn": _2, "o": _2, "org": _2, "p": _2, "parti": _2, "pp": _2, "press": _2, "r": _2, "s": _2, "t": _2, "tm": _2, "u": _2, "w": _2, "x": _2, "y": _2, "z": _2, "com": _3, "iopsys": _3, "123minsida": _3, "itcouldbewor": _3, "myspreadshop": _3 }], "sg": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "enscaled": _3 }], "sh": [1, { "com": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "hashbang": _3, "botda": _3, "lovable": _3, "platform": [0, { "ent": _3, "eu": _3, "us": _3 }], "now": _3 }], "si": [1, { "f5": _3, "gitapp": _3, "gitpage": _3 }], "sj": _2, "sk": _2, "sl": _4, "sm": _2, "sn": [1, { "art": _2, "com": _2, "edu": _2, "gouv": _2, "org": _2, "perso": _2, "univ": _2 }], "so": [1, { "com": _2, "edu": _2, "gov": _2, "me": _2, "net": _2, "org": _2, "surveys": _3 }], "sr": _2, "ss": [1, { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "me": _2, "net": _2, "org": _2, "sch": _2 }], "st": [1, { "co": _2, "com": _2, "consulado": _2, "edu": _2, "embaixada": _2, "mil": _2, "net": _2, "org": _2, "principe": _2, "saotome": _2, "store": _2, "helioho": _3, "kirara": _3, "noho": _3 }], "su": [1, { "abkhazia": _3, "adygeya": _3, "aktyubinsk": _3, "arkhangelsk": _3, "armenia": _3, "ashgabad": _3, "azerbaijan": _3, "balashov": _3, "bashkiria": _3, "bryansk": _3, "bukhara": _3, "chimkent": _3, "dagestan": _3, "east-kazakhstan": _3, "exnet": _3, "georgia": _3, "grozny": _3, "ivanovo": _3, "jambyl": _3, "kalmykia": _3, "kaluga": _3, "karacol": _3, "karaganda": _3, "karelia": _3, "khakassia": _3, "krasnodar": _3, "kurgan": _3, "kustanai": _3, "lenug": _3, "mangyshlak": _3, "mordovia": _3, "msk": _3, "murmansk": _3, "nalchik": _3, "navoi": _3, "north-kazakhstan": _3, "nov": _3, "obninsk": _3, "penza": _3, "pokrovsk": _3, "sochi": _3, "spb": _3, "tashkent": _3, "termez": _3, "togliatti": _3, "troitsk": _3, "tselinograd": _3, "tula": _3, "tuva": _3, "vladikavkaz": _3, "vladimir": _3, "vologda": _3 }], "sv": [1, { "com": _2, "edu": _2, "gob": _2, "org": _2, "red": _2 }], "sx": _10, "sy": _5, "sz": [1, { "ac": _2, "co": _2, "org": _2 }], "tc": _2, "td": _2, "tel": _2, "tf": [1, { "sch": _3 }], "tg": _2, "th": [1, { "ac": _2, "co": _2, "go": _2, "in": _2, "mi": _2, "net": _2, "or": _2, "online": _3, "shop": _3 }], "tj": [1, { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "go": _2, "gov": _2, "int": _2, "mil": _2, "name": _2, "net": _2, "nic": _2, "org": _2, "test": _2, "web": _2 }], "tk": _2, "tl": _10, "tm": [1, { "co": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "nom": _2, "org": _2 }], "tn": [1, { "com": _2, "ens": _2, "fin": _2, "gov": _2, "ind": _2, "info": _2, "intl": _2, "mincom": _2, "nat": _2, "net": _2, "org": _2, "perso": _2, "tourism": _2, "orangecloud": _3 }], "to": [1, { "611": _3, "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "oya": _3, "x0": _3, "quickconnect": _25, "vpnplus": _3 }], "tr": [1, { "av": _2, "bbs": _2, "bel": _2, "biz": _2, "com": _2, "dr": _2, "edu": _2, "gen": _2, "gov": _2, "info": _2, "k12": _2, "kep": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pol": _2, "tel": _2, "tsk": _2, "tv": _2, "web": _2, "nc": _10 }], "tt": [1, { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pro": _2 }], "tv": [1, { "better-than": _3, "dyndns": _3, "on-the-web": _3, "worse-than": _3, "from": _3, "sakura": _3 }], "tw": [1, { "club": _2, "com": [1, { "mymailer": _3 }], "ebiz": _2, "edu": _2, "game": _2, "gov": _2, "idv": _2, "mil": _2, "net": _2, "org": _2, "url": _3, "mydns": _3 }], "tz": [1, { "ac": _2, "co": _2, "go": _2, "hotel": _2, "info": _2, "me": _2, "mil": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2, "tv": _2 }], "ua": [1, { "com": _2, "edu": _2, "gov": _2, "in": _2, "net": _2, "org": _2, "cherkassy": _2, "cherkasy": _2, "chernigov": _2, "chernihiv": _2, "chernivtsi": _2, "chernovtsy": _2, "ck": _2, "cn": _2, "cr": _2, "crimea": _2, "cv": _2, "dn": _2, "dnepropetrovsk": _2, "dnipropetrovsk": _2, "donetsk": _2, "dp": _2, "if": _2, "ivano-frankivsk": _2, "kh": _2, "kharkiv": _2, "kharkov": _2, "kherson": _2, "khmelnitskiy": _2, "khmelnytskyi": _2, "kiev": _2, "kirovograd": _2, "km": _2, "kr": _2, "kropyvnytskyi": _2, "krym": _2, "ks": _2, "kv": _2, "kyiv": _2, "lg": _2, "lt": _2, "lugansk": _2, "luhansk": _2, "lutsk": _2, "lv": _2, "lviv": _2, "mk": _2, "mykolaiv": _2, "nikolaev": _2, "od": _2, "odesa": _2, "odessa": _2, "pl": _2, "poltava": _2, "rivne": _2, "rovno": _2, "rv": _2, "sb": _2, "sebastopol": _2, "sevastopol": _2, "sm": _2, "sumy": _2, "te": _2, "ternopil": _2, "uz": _2, "uzhgorod": _2, "uzhhorod": _2, "vinnica": _2, "vinnytsia": _2, "vn": _2, "volyn": _2, "yalta": _2, "zakarpattia": _2, "zaporizhzhe": _2, "zaporizhzhia": _2, "zhitomir": _2, "zhytomyr": _2, "zp": _2, "zt": _2, "cc": _3, "inf": _3, "ltd": _3, "cx": _3, "biz": _3, "co": _3, "pp": _3, "v": _3 }], "ug": [1, { "ac": _2, "co": _2, "com": _2, "edu": _2, "go": _2, "gov": _2, "mil": _2, "ne": _2, "or": _2, "org": _2, "sc": _2, "us": _2 }], "uk": [1, { "ac": _2, "co": [1, { "bytemark": [0, { "dh": _3, "vm": _3 }], "layershift": _46, "barsy": _3, "barsyonline": _3, "retrosnub": _56, "nh-serv": _3, "no-ip": _3, "adimo": _3, "myspreadshop": _3 }], "gov": [1, { "api": _3, "campaign": _3, "service": _3 }], "ltd": _2, "me": _2, "net": _2, "nhs": _2, "org": [1, { "glug": _3, "lug": _3, "lugs": _3, "affinitylottery": _3, "raffleentry": _3, "weeklylottery": _3 }], "plc": _2, "police": _2, "sch": _18, "conn": _3, "copro": _3, "hosp": _3, "independent-commission": _3, "independent-inquest": _3, "independent-inquiry": _3, "independent-panel": _3, "independent-review": _3, "public-inquiry": _3, "royal-commission": _3, "pymnt": _3, "barsy": _3, "nimsite": _3, "oraclegovcloudapps": _6 }], "us": [1, { "dni": _2, "isa": _2, "nsn": _2, "ak": _64, "al": _64, "ar": _64, "as": _64, "az": _64, "ca": _64, "co": _64, "ct": _64, "dc": _64, "de": [1, { "cc": _2, "lib": _3 }], "fl": _64, "ga": _64, "gu": _64, "hi": _65, "ia": _64, "id": _64, "il": _64, "in": _64, "ks": _64, "ky": _64, "la": _64, "ma": [1, { "k12": [1, { "chtr": _2, "paroch": _2, "pvt": _2 }], "cc": _2, "lib": _2 }], "md": _64, "me": _64, "mi": [1, { "k12": _2, "cc": _2, "lib": _2, "ann-arbor": _2, "cog": _2, "dst": _2, "eaton": _2, "gen": _2, "mus": _2, "tec": _2, "washtenaw": _2 }], "mn": _64, "mo": _64, "ms": _64, "mt": _64, "nc": _64, "nd": _65, "ne": _64, "nh": _64, "nj": _64, "nm": _64, "nv": _64, "ny": _64, "oh": _64, "ok": _64, "or": _64, "pa": _64, "pr": _64, "ri": _65, "sc": _64, "sd": _65, "tn": _64, "tx": _64, "ut": _64, "va": _64, "vi": _64, "vt": _64, "wa": _64, "wi": _64, "wv": [1, { "cc": _2 }], "wy": _64, "cloudns": _3, "is-by": _3, "land-4-sale": _3, "stuff-4-sale": _3, "heliohost": _3, "enscaled": [0, { "phx": _3 }], "mircloud": _3, "ngo": _3, "golffan": _3, "noip": _3, "pointto": _3, "freeddns": _3, "srv": [2, { "gh": _3, "gl": _3 }], "platterp": _3, "servername": _3 }], "uy": [1, { "com": _2, "edu": _2, "gub": _2, "mil": _2, "net": _2, "org": _2 }], "uz": [1, { "co": _2, "com": _2, "net": _2, "org": _2 }], "va": _2, "vc": [1, { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "gv": [2, { "d": _3 }], "0e": _6, "mydns": _3 }], "ve": [1, { "arts": _2, "bib": _2, "co": _2, "com": _2, "e12": _2, "edu": _2, "emprende": _2, "firm": _2, "gob": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "rar": _2, "rec": _2, "store": _2, "tec": _2, "web": _2 }], "vg": [1, { "edu": _2 }], "vi": [1, { "co": _2, "com": _2, "k12": _2, "net": _2, "org": _2 }], "vn": [1, { "ac": _2, "ai": _2, "biz": _2, "com": _2, "edu": _2, "gov": _2, "health": _2, "id": _2, "info": _2, "int": _2, "io": _2, "name": _2, "net": _2, "org": _2, "pro": _2, "angiang": _2, "bacgiang": _2, "backan": _2, "baclieu": _2, "bacninh": _2, "baria-vungtau": _2, "bentre": _2, "binhdinh": _2, "binhduong": _2, "binhphuoc": _2, "binhthuan": _2, "camau": _2, "cantho": _2, "caobang": _2, "daklak": _2, "daknong": _2, "danang": _2, "dienbien": _2, "dongnai": _2, "dongthap": _2, "gialai": _2, "hagiang": _2, "haiduong": _2, "haiphong": _2, "hanam": _2, "hanoi": _2, "hatinh": _2, "haugiang": _2, "hoabinh": _2, "hungyen": _2, "khanhhoa": _2, "kiengiang": _2, "kontum": _2, "laichau": _2, "lamdong": _2, "langson": _2, "laocai": _2, "longan": _2, "namdinh": _2, "nghean": _2, "ninhbinh": _2, "ninhthuan": _2, "phutho": _2, "phuyen": _2, "quangbinh": _2, "quangnam": _2, "quangngai": _2, "quangninh": _2, "quangtri": _2, "soctrang": _2, "sonla": _2, "tayninh": _2, "thaibinh": _2, "thainguyen": _2, "thanhhoa": _2, "thanhphohochiminh": _2, "thuathienhue": _2, "tiengiang": _2, "travinh": _2, "tuyenquang": _2, "vinhlong": _2, "vinhphuc": _2, "yenbai": _2 }], "vu": _45, "wf": [1, { "biz": _3, "sch": _3 }], "ws": [1, { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "advisor": _6, "cloud66": _3, "dyndns": _3, "mypets": _3 }], "yt": [1, { "org": _3 }], "xn--mgbaam7a8h": _2, "امارات": _2, "xn--y9a3aq": _2, "հայ": _2, "xn--54b7fta0cc": _2, "বাংলা": _2, "xn--90ae": _2, "бг": _2, "xn--mgbcpq6gpa1a": _2, "البحرين": _2, "xn--90ais": _2, "бел": _2, "xn--fiqs8s": _2, "中国": _2, "xn--fiqz9s": _2, "中國": _2, "xn--lgbbat1ad8j": _2, "الجزائر": _2, "xn--wgbh1c": _2, "مصر": _2, "xn--e1a4c": _2, "ею": _2, "xn--qxa6a": _2, "ευ": _2, "xn--mgbah1a3hjkrd": _2, "موريتانيا": _2, "xn--node": _2, "გე": _2, "xn--qxam": _2, "ελ": _2, "xn--j6w193g": [1, { "xn--gmqw5a": _2, "xn--55qx5d": _2, "xn--mxtq1m": _2, "xn--wcvs22d": _2, "xn--uc0atv": _2, "xn--od0alg": _2 }], "香港": [1, { "個人": _2, "公司": _2, "政府": _2, "教育": _2, "組織": _2, "網絡": _2 }], "xn--2scrj9c": _2, "ಭಾರತ": _2, "xn--3hcrj9c": _2, "ଭାରତ": _2, "xn--45br5cyl": _2, "ভাৰত": _2, "xn--h2breg3eve": _2, "भारतम्": _2, "xn--h2brj9c8c": _2, "भारोत": _2, "xn--mgbgu82a": _2, "ڀارت": _2, "xn--rvc1e0am3e": _2, "ഭാരതം": _2, "xn--h2brj9c": _2, "भारत": _2, "xn--mgbbh1a": _2, "بارت": _2, "xn--mgbbh1a71e": _2, "بھارت": _2, "xn--fpcrj9c3d": _2, "భారత్": _2, "xn--gecrj9c": _2, "ભારત": _2, "xn--s9brj9c": _2, "ਭਾਰਤ": _2, "xn--45brj9c": _2, "ভারত": _2, "xn--xkc2dl3a5ee0h": _2, "இந்தியா": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2, "xn--mgbtx2b": _2, "عراق": _2, "xn--mgbayh7gpa": _2, "الاردن": _2, "xn--3e0b707e": _2, "한국": _2, "xn--80ao21a": _2, "қаз": _2, "xn--q7ce6a": _2, "ລາວ": _2, "xn--fzc2c9e2c": _2, "ලංකා": _2, "xn--xkc2al3hye2a": _2, "இலங்கை": _2, "xn--mgbc0a9azcg": _2, "المغرب": _2, "xn--d1alf": _2, "мкд": _2, "xn--l1acc": _2, "мон": _2, "xn--mix891f": _2, "澳門": _2, "xn--mix082f": _2, "澳门": _2, "xn--mgbx4cd0ab": _2, "مليسيا": _2, "xn--mgb9awbf": _2, "عمان": _2, "xn--mgbai9azgqp6j": _2, "پاکستان": _2, "xn--mgbai9a5eva00b": _2, "پاكستان": _2, "xn--ygbi2ammx": _2, "فلسطين": _2, "xn--90a3ac": [1, { "xn--80au": _2, "xn--90azh": _2, "xn--d1at": _2, "xn--c1avg": _2, "xn--o1ac": _2, "xn--o1ach": _2 }], "срб": [1, { "ак": _2, "обр": _2, "од": _2, "орг": _2, "пр": _2, "упр": _2 }], "xn--p1ai": _2, "рф": _2, "xn--wgbl6a": _2, "قطر": _2, "xn--mgberp4a5d4ar": _2, "السعودية": _2, "xn--mgberp4a5d4a87g": _2, "السعودیة": _2, "xn--mgbqly7c0a67fbc": _2, "السعودیۃ": _2, "xn--mgbqly7cvafr": _2, "السعوديه": _2, "xn--mgbpl2fh": _2, "سودان": _2, "xn--yfro4i67o": _2, "新加坡": _2, "xn--clchc0ea0b2g2a9gcd": _2, "சிங்கப்பூர்": _2, "xn--ogbpf8fl": _2, "سورية": _2, "xn--mgbtf8fl": _2, "سوريا": _2, "xn--o3cw4h": [1, { "xn--o3cyx2a": _2, "xn--12co0c3b4eva": _2, "xn--m3ch0j3a": _2, "xn--h3cuzk1di": _2, "xn--12c1fe0br": _2, "xn--12cfi8ixb8l": _2 }], "ไทย": [1, { "ทหาร": _2, "ธุรกิจ": _2, "เน็ต": _2, "รัฐบาล": _2, "ศึกษา": _2, "องค์กร": _2 }], "xn--pgbs0dh": _2, "تونس": _2, "xn--kpry57d": _2, "台灣": _2, "xn--kprw13d": _2, "台湾": _2, "xn--nnx388a": _2, "臺灣": _2, "xn--j1amh": _2, "укр": _2, "xn--mgb2ddes": _2, "اليمن": _2, "xxx": _2, "ye": _5, "za": [0, { "ac": _2, "agric": _2, "alt": _2, "co": _2, "edu": _2, "gov": _2, "grondar": _2, "law": _2, "mil": _2, "net": _2, "ngo": _2, "nic": _2, "nis": _2, "nom": _2, "org": _2, "school": _2, "tm": _2, "web": _2 }], "zm": [1, { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "mil": _2, "net": _2, "org": _2, "sch": _2 }], "zw": [1, { "ac": _2, "co": _2, "gov": _2, "mil": _2, "org": _2 }], "aaa": _2, "aarp": _2, "abb": _2, "abbott": _2, "abbvie": _2, "abc": _2, "able": _2, "abogado": _2, "abudhabi": _2, "academy": [1, { "official": _3 }], "accenture": _2, "accountant": _2, "accountants": _2, "aco": _2, "actor": _2, "ads": _2, "adult": _2, "aeg": _2, "aetna": _2, "afl": _2, "africa": _2, "agakhan": _2, "agency": _2, "aig": _2, "airbus": _2, "airforce": _2, "airtel": _2, "akdn": _2, "alibaba": _2, "alipay": _2, "allfinanz": _2, "allstate": _2, "ally": _2, "alsace": _2, "alstom": _2, "amazon": _2, "americanexpress": _2, "americanfamily": _2, "amex": _2, "amfam": _2, "amica": _2, "amsterdam": _2, "analytics": _2, "android": _2, "anquan": _2, "anz": _2, "aol": _2, "apartments": _2, "app": [1, { "adaptable": _3, "aiven": _3, "beget": _6, "brave": _7, "clerk": _3, "clerkstage": _3, "wnext": _3, "csb": [2, { "preview": _3 }], "convex": _3, "deta": _3, "ondigitalocean": _3, "easypanel": _3, "encr": [2, { "frontend": _3 }], "evervault": _8, "expo": [2, { "staging": _3 }], "edgecompute": _3, "on-fleek": _3, "flutterflow": _3, "e2b": _3, "framer": _3, "github": _3, "hosted": _6, "run": [0, { "*": _3, "mtls": _6 }], "web": _3, "hasura": _3, "botdash": _3, "loginline": _3, "lovable": _3, "luyani": _3, "medusajs": _3, "messerli": _3, "netfy": _3, "netlify": _3, "ngrok": _3, "ngrok-free": _3, "developer": _6, "noop": _3, "northflank": _6, "upsun": _6, "railway": [0, { "up": _3 }], "replit": _9, "nyat": _3, "snowflake": [0, { "*": _3, "privatelink": _6 }], "streamlit": _3, "storipress": _3, "telebit": _3, "typedream": _3, "vercel": _3, "bookonline": _3, "wdh": _3, "windsurf": _3, "zeabur": _3, "zerops": _6 }], "apple": _2, "aquarelle": _2, "arab": _2, "aramco": _2, "archi": _2, "army": _2, "art": _2, "arte": _2, "asda": _2, "associates": _2, "athleta": _2, "attorney": _2, "auction": _2, "audi": _2, "audible": _2, "audio": _2, "auspost": _2, "author": _2, "auto": _2, "autos": _2, "aws": [1, { "on": [0, { "af-south-1": _11, "ap-east-1": _11, "ap-northeast-1": _11, "ap-northeast-2": _11, "ap-northeast-3": _11, "ap-south-1": _11, "ap-south-2": _11, "ap-southeast-1": _11, "ap-southeast-2": _11, "ap-southeast-3": _11, "ap-southeast-4": _11, "ap-southeast-5": _11, "ca-central-1": _11, "ca-west-1": _11, "eu-central-1": _11, "eu-central-2": _11, "eu-north-1": _11, "eu-south-1": _11, "eu-south-2": _11, "eu-west-1": _11, "eu-west-2": _11, "eu-west-3": _11, "il-central-1": _11, "me-central-1": _11, "me-south-1": _11, "sa-east-1": _11, "us-east-1": _11, "us-east-2": _11, "us-west-1": _11, "us-west-2": _11, "us-gov-east-1": _12, "us-gov-west-1": _12 }], "sagemaker": [0, { "ap-northeast-1": _14, "ap-northeast-2": _14, "ap-south-1": _14, "ap-southeast-1": _14, "ap-southeast-2": _14, "ca-central-1": _16, "eu-central-1": _14, "eu-west-1": _14, "eu-west-2": _14, "us-east-1": _16, "us-east-2": _16, "us-west-2": _16, "af-south-1": _13, "ap-east-1": _13, "ap-northeast-3": _13, "ap-south-2": _15, "ap-southeast-3": _13, "ap-southeast-4": _15, "ca-west-1": [0, { "notebook": _3, "notebook-fips": _3 }], "eu-central-2": _13, "eu-north-1": _13, "eu-south-1": _13, "eu-south-2": _13, "eu-west-3": _13, "il-central-1": _13, "me-central-1": _13, "me-south-1": _13, "sa-east-1": _13, "us-gov-east-1": _17, "us-gov-west-1": _17, "us-west-1": [0, { "notebook": _3, "notebook-fips": _3, "studio": _3 }], "experiments": _6 }], "repost": [0, { "private": _6 }] }], "axa": _2, "azure": _2, "baby": _2, "baidu": _2, "banamex": _2, "band": _2, "bank": _2, "bar": _2, "barcelona": _2, "barclaycard": _2, "barclays": _2, "barefoot": _2, "bargains": _2, "baseball": _2, "basketball": [1, { "aus": _3, "nz": _3 }], "bauhaus": _2, "bayern": _2, "bbc": _2, "bbt": _2, "bbva": _2, "bcg": _2, "bcn": _2, "beats": _2, "beauty": _2, "beer": _2, "berlin": _2, "best": _2, "bestbuy": _2, "bet": _2, "bharti": _2, "bible": _2, "bid": _2, "bike": _2, "bing": _2, "bingo": _2, "bio": _2, "black": _2, "blackfriday": _2, "blockbuster": _2, "blog": _2, "bloomberg": _2, "blue": _2, "bms": _2, "bmw": _2, "bnpparibas": _2, "boats": _2, "boehringer": _2, "bofa": _2, "bom": _2, "bond": _2, "boo": _2, "book": _2, "booking": _2, "bosch": _2, "bostik": _2, "boston": _2, "bot": _2, "boutique": _2, "box": _2, "bradesco": _2, "bridgestone": _2, "broadway": _2, "broker": _2, "brother": _2, "brussels": _2, "build": [1, { "v0": _3, "windsurf": _3 }], "builders": [1, { "cloudsite": _3 }], "business": _19, "buy": _2, "buzz": _2, "bzh": _2, "cab": _2, "cafe": _2, "cal": _2, "call": _2, "calvinklein": _2, "cam": _2, "camera": _2, "camp": [1, { "emf": [0, { "at": _3 }] }], "canon": _2, "capetown": _2, "capital": _2, "capitalone": _2, "car": _2, "caravan": _2, "cards": _2, "care": _2, "career": _2, "careers": _2, "cars": _2, "casa": [1, { "nabu": [0, { "ui": _3 }] }], "case": _2, "cash": _2, "casino": _2, "catering": _2, "catholic": _2, "cba": _2, "cbn": _2, "cbre": _2, "center": _2, "ceo": _2, "cern": _2, "cfa": _2, "cfd": _2, "chanel": _2, "channel": _2, "charity": _2, "chase": _2, "chat": _2, "cheap": _2, "chintai": _2, "christmas": _2, "chrome": _2, "church": _2, "cipriani": _2, "circle": _2, "cisco": _2, "citadel": _2, "citi": _2, "citic": _2, "city": _2, "claims": _2, "cleaning": _2, "click": _2, "clinic": _2, "clinique": _2, "clothing": _2, "cloud": [1, { "convex": _3, "elementor": _3, "encoway": [0, { "eu": _3 }], "statics": _6, "ravendb": _3, "axarnet": [0, { "es-1": _3 }], "diadem": _3, "jelastic": [0, { "vip": _3 }], "jele": _3, "jenv-aruba": [0, { "aruba": [0, { "eur": [0, { "it1": _3 }] }], "it1": _3 }], "keliweb": [2, { "cs": _3 }], "oxa": [2, { "tn": _3, "uk": _3 }], "primetel": [2, { "uk": _3 }], "reclaim": [0, { "ca": _3, "uk": _3, "us": _3 }], "trendhosting": [0, { "ch": _3, "de": _3 }], "jotelulu": _3, "kuleuven": _3, "laravel": _3, "linkyard": _3, "magentosite": _6, "matlab": _3, "observablehq": _3, "perspecta": _3, "vapor": _3, "on-rancher": _6, "scw": [0, { "baremetal": [0, { "fr-par-1": _3, "fr-par-2": _3, "nl-ams-1": _3 }], "fr-par": [0, { "cockpit": _3, "ddl": _3, "dtwh": _3, "fnc": [2, { "functions": _3 }], "ifr": _3, "k8s": _21, "kafk": _3, "mgdb": _3, "rdb": _3, "s3": _3, "s3-website": _3, "scbl": _3, "whm": _3 }], "instances": [0, { "priv": _3, "pub": _3 }], "k8s": _3, "nl-ams": [0, { "cockpit": _3, "ddl": _3, "dtwh": _3, "ifr": _3, "k8s": _21, "kafk": _3, "mgdb": _3, "rdb": _3, "s3": _3, "s3-website": _3, "scbl": _3, "whm": _3 }], "pl-waw": [0, { "cockpit": _3, "ddl": _3, "dtwh": _3, "ifr": _3, "k8s": _21, "kafk": _3, "mgdb": _3, "rdb": _3, "s3": _3, "s3-website": _3, "scbl": _3 }], "scalebook": _3, "smartlabeling": _3 }], "servebolt": _3, "onstackit": [0, { "runs": _3 }], "trafficplex": _3, "unison-services": _3, "urown": _3, "voorloper": _3, "zap": _3 }], "club": [1, { "cloudns": _3, "jele": _3, "barsy": _3 }], "clubmed": _2, "coach": _2, "codes": [1, { "owo": _6 }], "coffee": _2, "college": _2, "cologne": _2, "commbank": _2, "community": [1, { "nog": _3, "ravendb": _3, "myforum": _3 }], "company": _2, "compare": _2, "computer": _2, "comsec": _2, "condos": _2, "construction": _2, "consulting": _2, "contact": _2, "contractors": _2, "cooking": _2, "cool": [1, { "elementor": _3, "de": _3 }], "corsica": _2, "country": _2, "coupon": _2, "coupons": _2, "courses": _2, "cpa": _2, "credit": _2, "creditcard": _2, "creditunion": _2, "cricket": _2, "crown": _2, "crs": _2, "cruise": _2, "cruises": _2, "cuisinella": _2, "cymru": _2, "cyou": _2, "dad": _2, "dance": _2, "data": _2, "date": _2, "dating": _2, "datsun": _2, "day": _2, "dclk": _2, "dds": _2, "deal": _2, "dealer": _2, "deals": _2, "degree": _2, "delivery": _2, "dell": _2, "deloitte": _2, "delta": _2, "democrat": _2, "dental": _2, "dentist": _2, "desi": _2, "design": [1, { "graphic": _3, "bss": _3 }], "dev": [1, { "12chars": _3, "myaddr": _3, "panel": _3, "lcl": _6, "lclstage": _6, "stg": _6, "stgstage": _6, "pages": _3, "r2": _3, "workers": _3, "deno": _3, "deno-staging": _3, "deta": _3, "lp": [2, { "api": _3, "objects": _3 }], "evervault": _8, "fly": _3, "githubpreview": _3, "gateway": _6, "botdash": _3, "inbrowser": _6, "is-a-good": _3, "is-a": _3, "iserv": _3, "runcontainers": _3, "localcert": [0, { "user": _6 }], "loginline": _3, "barsy": _3, "mediatech": _3, "modx": _3, "ngrok": _3, "ngrok-free": _3, "is-a-fullstack": _3, "is-cool": _3, "is-not-a": _3, "localplayer": _3, "xmit": _3, "platter-app": _3, "replit": [2, { "archer": _3, "bones": _3, "canary": _3, "global": _3, "hacker": _3, "id": _3, "janeway": _3, "kim": _3, "kira": _3, "kirk": _3, "odo": _3, "paris": _3, "picard": _3, "pike": _3, "prerelease": _3, "reed": _3, "riker": _3, "sisko": _3, "spock": _3, "staging": _3, "sulu": _3, "tarpit": _3, "teams": _3, "tucker": _3, "wesley": _3, "worf": _3 }], "crm": [0, { "d": _6, "w": _6, "wa": _6, "wb": _6, "wc": _6, "wd": _6, "we": _6, "wf": _6 }], "erp": _48, "vercel": _3, "webhare": _6, "hrsn": _3 }], "dhl": _2, "diamonds": _2, "diet": _2, "digital": [1, { "cloudapps": [2, { "london": _3 }] }], "direct": [1, { "libp2p": _3 }], "directory": _2, "discount": _2, "discover": _2, "dish": _2, "diy": _2, "dnp": _2, "docs": _2, "doctor": _2, "dog": _2, "domains": _2, "dot": _2, "download": _2, "drive": _2, "dtv": _2, "dubai": _2, "dunlop": _2, "dupont": _2, "durban": _2, "dvag": _2, "dvr": _2, "earth": _2, "eat": _2, "eco": _2, "edeka": _2, "education": _19, "email": [1, { "crisp": [0, { "on": _3 }], "tawk": _50, "tawkto": _50 }], "emerck": _2, "energy": _2, "engineer": _2, "engineering": _2, "enterprises": _2, "epson": _2, "equipment": _2, "ericsson": _2, "erni": _2, "esq": _2, "estate": [1, { "compute": _6 }], "eurovision": _2, "eus": [1, { "party": _51 }], "events": [1, { "koobin": _3, "co": _3 }], "exchange": _2, "expert": _2, "exposed": _2, "express": _2, "extraspace": _2, "fage": _2, "fail": _2, "fairwinds": _2, "faith": _2, "family": _2, "fan": _2, "fans": _2, "farm": [1, { "storj": _3 }], "farmers": _2, "fashion": _2, "fast": _2, "fedex": _2, "feedback": _2, "ferrari": _2, "ferrero": _2, "fidelity": _2, "fido": _2, "film": _2, "final": _2, "finance": _2, "financial": _19, "fire": _2, "firestone": _2, "firmdale": _2, "fish": _2, "fishing": _2, "fit": _2, "fitness": _2, "flickr": _2, "flights": _2, "flir": _2, "florist": _2, "flowers": _2, "fly": _2, "foo": _2, "food": _2, "football": _2, "ford": _2, "forex": _2, "forsale": _2, "forum": _2, "foundation": _2, "fox": _2, "free": _2, "fresenius": _2, "frl": _2, "frogans": _2, "frontier": _2, "ftr": _2, "fujitsu": _2, "fun": _2, "fund": _2, "furniture": _2, "futbol": _2, "fyi": _2, "gal": _2, "gallery": _2, "gallo": _2, "gallup": _2, "game": _2, "games": [1, { "pley": _3, "sheezy": _3 }], "gap": _2, "garden": _2, "gay": [1, { "pages": _3 }], "gbiz": _2, "gdn": [1, { "cnpy": _3 }], "gea": _2, "gent": _2, "genting": _2, "george": _2, "ggee": _2, "gift": _2, "gifts": _2, "gives": _2, "giving": _2, "glass": _2, "gle": _2, "global": [1, { "appwrite": _3 }], "globo": _2, "gmail": _2, "gmbh": _2, "gmo": _2, "gmx": _2, "godaddy": _2, "gold": _2, "goldpoint": _2, "golf": _2, "goo": _2, "goodyear": _2, "goog": [1, { "cloud": _3, "translate": _3, "usercontent": _6 }], "google": _2, "gop": _2, "got": _2, "grainger": _2, "graphics": _2, "gratis": _2, "green": _2, "gripe": _2, "grocery": _2, "group": [1, { "discourse": _3 }], "gucci": _2, "guge": _2, "guide": _2, "guitars": _2, "guru": _2, "hair": _2, "hamburg": _2, "hangout": _2, "haus": _2, "hbo": _2, "hdfc": _2, "hdfcbank": _2, "health": [1, { "hra": _3 }], "healthcare": _2, "help": _2, "helsinki": _2, "here": _2, "hermes": _2, "hiphop": _2, "hisamitsu": _2, "hitachi": _2, "hiv": _2, "hkt": _2, "hockey": _2, "holdings": _2, "holiday": _2, "homedepot": _2, "homegoods": _2, "homes": _2, "homesense": _2, "honda": _2, "horse": _2, "hospital": _2, "host": [1, { "cloudaccess": _3, "freesite": _3, "easypanel": _3, "fastvps": _3, "myfast": _3, "tempurl": _3, "wpmudev": _3, "iserv": _3, "jele": _3, "mircloud": _3, "wp2": _3, "half": _3 }], "hosting": [1, { "opencraft": _3 }], "hot": _2, "hotel": _2, "hotels": _2, "hotmail": _2, "house": _2, "how": _2, "hsbc": _2, "hughes": _2, "hyatt": _2, "hyundai": _2, "ibm": _2, "icbc": _2, "ice": _2, "icu": _2, "ieee": _2, "ifm": _2, "ikano": _2, "imamat": _2, "imdb": _2, "immo": _2, "immobilien": _2, "inc": _2, "industries": _2, "infiniti": _2, "ing": _2, "ink": _2, "institute": _2, "insurance": _2, "insure": _2, "international": _2, "intuit": _2, "investments": _2, "ipiranga": _2, "irish": _2, "ismaili": _2, "ist": _2, "istanbul": _2, "itau": _2, "itv": _2, "jaguar": _2, "java": _2, "jcb": _2, "jeep": _2, "jetzt": _2, "jewelry": _2, "jio": _2, "jll": _2, "jmp": _2, "jnj": _2, "joburg": _2, "jot": _2, "joy": _2, "jpmorgan": _2, "jprs": _2, "juegos": _2, "juniper": _2, "kaufen": _2, "kddi": _2, "kerryhotels": _2, "kerryproperties": _2, "kfh": _2, "kia": _2, "kids": _2, "kim": _2, "kindle": _2, "kitchen": _2, "kiwi": _2, "koeln": _2, "komatsu": _2, "kosher": _2, "kpmg": _2, "kpn": _2, "krd": [1, { "co": _3, "edu": _3 }], "kred": _2, "kuokgroup": _2, "kyoto": _2, "lacaixa": _2, "lamborghini": _2, "lamer": _2, "land": _2, "landrover": _2, "lanxess": _2, "lasalle": _2, "lat": _2, "latino": _2, "latrobe": _2, "law": _2, "lawyer": _2, "lds": _2, "lease": _2, "leclerc": _2, "lefrak": _2, "legal": _2, "lego": _2, "lexus": _2, "lgbt": _2, "lidl": _2, "life": _2, "lifeinsurance": _2, "lifestyle": _2, "lighting": _2, "like": _2, "lilly": _2, "limited": _2, "limo": _2, "lincoln": _2, "link": [1, { "myfritz": _3, "cyon": _3, "dweb": _6, "inbrowser": _6, "nftstorage": _59, "mypep": _3, "storacha": _59, "w3s": _59 }], "live": [1, { "aem": _3, "hlx": _3, "ewp": _6 }], "living": _2, "llc": _2, "llp": _2, "loan": _2, "loans": _2, "locker": _2, "locus": _2, "lol": [1, { "omg": _3 }], "london": _2, "lotte": _2, "lotto": _2, "love": _2, "lpl": _2, "lplfinancial": _2, "ltd": _2, "ltda": _2, "lundbeck": _2, "luxe": _2, "luxury": _2, "madrid": _2, "maif": _2, "maison": _2, "makeup": _2, "man": _2, "management": _2, "mango": _2, "map": _2, "market": _2, "marketing": _2, "markets": _2, "marriott": _2, "marshalls": _2, "mattel": _2, "mba": _2, "mckinsey": _2, "med": _2, "media": _60, "meet": _2, "melbourne": _2, "meme": _2, "memorial": _2, "men": _2, "menu": [1, { "barsy": _3, "barsyonline": _3 }], "merck": _2, "merckmsd": _2, "miami": _2, "microsoft": _2, "mini": _2, "mint": _2, "mit": _2, "mitsubishi": _2, "mlb": _2, "mls": _2, "mma": _2, "mobile": _2, "moda": _2, "moe": _2, "moi": _2, "mom": _2, "monash": _2, "money": _2, "monster": _2, "mormon": _2, "mortgage": _2, "moscow": _2, "moto": _2, "motorcycles": _2, "mov": _2, "movie": _2, "msd": _2, "mtn": _2, "mtr": _2, "music": _2, "nab": _2, "nagoya": _2, "navy": _2, "nba": _2, "nec": _2, "netbank": _2, "netflix": _2, "network": [1, { "aem": _3, "alces": _6, "co": _3, "arvo": _3, "azimuth": _3, "tlon": _3 }], "neustar": _2, "new": _2, "news": [1, { "noticeable": _3 }], "next": _2, "nextdirect": _2, "nexus": _2, "nfl": _2, "ngo": _2, "nhk": _2, "nico": _2, "nike": _2, "nikon": _2, "ninja": _2, "nissan": _2, "nissay": _2, "nokia": _2, "norton": _2, "now": _2, "nowruz": _2, "nowtv": _2, "nra": _2, "nrw": _2, "ntt": _2, "nyc": _2, "obi": _2, "observer": _2, "office": _2, "okinawa": _2, "olayan": _2, "olayangroup": _2, "ollo": _2, "omega": _2, "one": [1, { "kin": _6, "service": _3 }], "ong": [1, { "obl": _3 }], "onl": _2, "online": [1, { "eero": _3, "eero-stage": _3, "websitebuilder": _3, "barsy": _3 }], "ooo": _2, "open": _2, "oracle": _2, "orange": [1, { "tech": _3 }], "organic": _2, "origins": _2, "osaka": _2, "otsuka": _2, "ott": _2, "ovh": [1, { "nerdpol": _3 }], "page": [1, { "aem": _3, "hlx": _3, "translated": _3, "codeberg": _3, "heyflow": _3, "prvcy": _3, "rocky": _3, "pdns": _3, "plesk": _3 }], "panasonic": _2, "paris": _2, "pars": _2, "partners": _2, "parts": _2, "party": _2, "pay": _2, "pccw": _2, "pet": _2, "pfizer": _2, "pharmacy": _2, "phd": _2, "philips": _2, "phone": _2, "photo": _2, "photography": _2, "photos": _60, "physio": _2, "pics": _2, "pictet": _2, "pictures": [1, { "1337": _3 }], "pid": _2, "pin": _2, "ping": _2, "pink": _2, "pioneer": _2, "pizza": [1, { "ngrok": _3 }], "place": _19, "play": _2, "playstation": _2, "plumbing": _2, "plus": _2, "pnc": _2, "pohl": _2, "poker": _2, "politie": _2, "porn": _2, "praxi": _2, "press": _2, "prime": _2, "prod": _2, "productions": _2, "prof": _2, "progressive": _2, "promo": _2, "properties": _2, "property": _2, "protection": _2, "pru": _2, "prudential": _2, "pub": [1, { "id": _6, "kin": _6, "barsy": _3 }], "pwc": _2, "qpon": _2, "quebec": _2, "quest": _2, "racing": _2, "radio": _2, "read": _2, "realestate": _2, "realtor": _2, "realty": _2, "recipes": _2, "red": _2, "redstone": _2, "redumbrella": _2, "rehab": _2, "reise": _2, "reisen": _2, "reit": _2, "reliance": _2, "ren": _2, "rent": _2, "rentals": _2, "repair": _2, "report": _2, "republican": _2, "rest": _2, "restaurant": _2, "review": _2, "reviews": [1, { "aem": _3 }], "rexroth": _2, "rich": _2, "richardli": _2, "ricoh": _2, "ril": _2, "rio": _2, "rip": [1, { "clan": _3 }], "rocks": [1, { "myddns": _3, "stackit": _3, "lima-city": _3, "webspace": _3 }], "rodeo": _2, "rogers": _2, "room": _2, "rsvp": _2, "rugby": _2, "ruhr": _2, "run": [1, { "appwrite": _6, "development": _3, "ravendb": _3, "liara": [2, { "iran": _3 }], "servers": _3, "lovable": _3, "build": _6, "code": _6, "database": _6, "migration": _6, "onporter": _3, "repl": _3, "stackit": _3, "val": _48, "vercel": _3, "wix": _3 }], "rwe": _2, "ryukyu": _2, "saarland": _2, "safe": _2, "safety": _2, "sakura": _2, "sale": _2, "salon": _2, "samsclub": _2, "samsung": _2, "sandvik": _2, "sandvikcoromant": _2, "sanofi": _2, "sap": _2, "sarl": _2, "sas": _2, "save": _2, "saxo": _2, "sbi": _2, "sbs": _2, "scb": _2, "schaeffler": _2, "schmidt": _2, "scholarships": _2, "school": _2, "schule": _2, "schwarz": _2, "science": _2, "scot": [1, { "gov": [2, { "service": _3 }] }], "search": _2, "seat": _2, "secure": _2, "security": _2, "seek": _2, "select": _2, "sener": _2, "services": [1, { "loginline": _3 }], "seven": _2, "sew": _2, "sex": _2, "sexy": _2, "sfr": _2, "shangrila": _2, "sharp": _2, "shell": _2, "shia": _2, "shiksha": _2, "shoes": _2, "shop": [1, { "base": _3, "hoplix": _3, "barsy": _3, "barsyonline": _3, "shopware": _3 }], "shopping": _2, "shouji": _2, "show": _2, "silk": _2, "sina": _2, "singles": _2, "site": [1, { "square": _3, "canva": _22, "cloudera": _6, "convex": _3, "cyon": _3, "caffeine": _3, "fastvps": _3, "figma": _3, "preview": _3, "heyflow": _3, "jele": _3, "jouwweb": _3, "loginline": _3, "barsy": _3, "notion": _3, "omniwe": _3, "opensocial": _3, "madethis": _3, "platformsh": _6, "tst": _6, "byen": _3, "srht": _3, "novecore": _3, "cpanel": _3, "wpsquared": _3 }], "ski": _2, "skin": _2, "sky": _2, "skype": _2, "sling": _2, "smart": _2, "smile": _2, "sncf": _2, "soccer": _2, "social": _2, "softbank": _2, "software": _2, "sohu": _2, "solar": _2, "solutions": _2, "song": _2, "sony": _2, "soy": _2, "spa": _2, "space": [1, { "myfast": _3, "heiyu": _3, "hf": [2, { "static": _3 }], "app-ionos": _3, "project": _3, "uber": _3, "xs4all": _3 }], "sport": _2, "spot": _2, "srl": _2, "stada": _2, "staples": _2, "star": _2, "statebank": _2, "statefarm": _2, "stc": _2, "stcgroup": _2, "stockholm": _2, "storage": _2, "store": [1, { "barsy": _3, "sellfy": _3, "shopware": _3, "storebase": _3 }], "stream": _2, "studio": _2, "study": _2, "style": _2, "sucks": _2, "supplies": _2, "supply": _2, "support": [1, { "barsy": _3 }], "surf": _2, "surgery": _2, "suzuki": _2, "swatch": _2, "swiss": _2, "sydney": _2, "systems": [1, { "knightpoint": _3 }], "tab": _2, "taipei": _2, "talk": _2, "taobao": _2, "target": _2, "tatamotors": _2, "tatar": _2, "tattoo": _2, "tax": _2, "taxi": _2, "tci": _2, "tdk": _2, "team": [1, { "discourse": _3, "jelastic": _3 }], "tech": [1, { "cleverapps": _3 }], "technology": _19, "temasek": _2, "tennis": _2, "teva": _2, "thd": _2, "theater": _2, "theatre": _2, "tiaa": _2, "tickets": _2, "tienda": _2, "tips": _2, "tires": _2, "tirol": _2, "tjmaxx": _2, "tjx": _2, "tkmaxx": _2, "tmall": _2, "today": [1, { "prequalifyme": _3 }], "tokyo": _2, "tools": [1, { "addr": _47, "myaddr": _3 }], "top": [1, { "ntdll": _3, "wadl": _6 }], "toray": _2, "toshiba": _2, "total": _2, "tours": _2, "town": _2, "toyota": _2, "toys": _2, "trade": _2, "trading": _2, "training": _2, "travel": _2, "travelers": _2, "travelersinsurance": _2, "trust": _2, "trv": _2, "tube": _2, "tui": _2, "tunes": _2, "tushu": _2, "tvs": _2, "ubank": _2, "ubs": _2, "unicom": _2, "university": _2, "uno": _2, "uol": _2, "ups": _2, "vacations": _2, "vana": _2, "vanguard": _2, "vegas": _2, "ventures": _2, "verisign": _2, "versicherung": _2, "vet": _2, "viajes": _2, "video": _2, "vig": _2, "viking": _2, "villas": _2, "vin": _2, "vip": [1, { "hidns": _3 }], "virgin": _2, "visa": _2, "vision": _2, "viva": _2, "vivo": _2, "vlaanderen": _2, "vodka": _2, "volvo": _2, "vote": _2, "voting": _2, "voto": _2, "voyage": _2, "wales": _2, "walmart": _2, "walter": _2, "wang": _2, "wanggou": _2, "watch": _2, "watches": _2, "weather": _2, "weatherchannel": _2, "webcam": _2, "weber": _2, "website": _60, "wed": _2, "wedding": _2, "weibo": _2, "weir": _2, "whoswho": _2, "wien": _2, "wiki": _60, "williamhill": _2, "win": _2, "windows": _2, "wine": _2, "winners": _2, "wme": _2, "wolterskluwer": _2, "woodside": _2, "work": _2, "works": _2, "world": _2, "wow": _2, "wtc": _2, "wtf": _2, "xbox": _2, "xerox": _2, "xihuan": _2, "xin": _2, "xn--11b4c3d": _2, "कॉम": _2, "xn--1ck2e1b": _2, "セール": _2, "xn--1qqw23a": _2, "佛山": _2, "xn--30rr7y": _2, "慈善": _2, "xn--3bst00m": _2, "集团": _2, "xn--3ds443g": _2, "在线": _2, "xn--3pxu8k": _2, "点看": _2, "xn--42c2d9a": _2, "คอม": _2, "xn--45q11c": _2, "八卦": _2, "xn--4gbrim": _2, "موقع": _2, "xn--55qw42g": _2, "公益": _2, "xn--55qx5d": _2, "公司": _2, "xn--5su34j936bgsg": _2, "香格里拉": _2, "xn--5tzm5g": _2, "网站": _2, "xn--6frz82g": _2, "移动": _2, "xn--6qq986b3xl": _2, "我爱你": _2, "xn--80adxhks": _2, "москва": _2, "xn--80aqecdr1a": _2, "католик": _2, "xn--80asehdb": _2, "онлайн": _2, "xn--80aswg": _2, "сайт": _2, "xn--8y0a063a": _2, "联通": _2, "xn--9dbq2a": _2, "קום": _2, "xn--9et52u": _2, "时尚": _2, "xn--9krt00a": _2, "微博": _2, "xn--b4w605ferd": _2, "淡马锡": _2, "xn--bck1b9a5dre4c": _2, "ファッション": _2, "xn--c1avg": _2, "орг": _2, "xn--c2br7g": _2, "नेट": _2, "xn--cck2b3b": _2, "ストア": _2, "xn--cckwcxetd": _2, "アマゾン": _2, "xn--cg4bki": _2, "삼성": _2, "xn--czr694b": _2, "商标": _2, "xn--czrs0t": _2, "商店": _2, "xn--czru2d": _2, "商城": _2, "xn--d1acj3b": _2, "дети": _2, "xn--eckvdtc9d": _2, "ポイント": _2, "xn--efvy88h": _2, "新闻": _2, "xn--fct429k": _2, "家電": _2, "xn--fhbei": _2, "كوم": _2, "xn--fiq228c5hs": _2, "中文网": _2, "xn--fiq64b": _2, "中信": _2, "xn--fjq720a": _2, "娱乐": _2, "xn--flw351e": _2, "谷歌": _2, "xn--fzys8d69uvgm": _2, "電訊盈科": _2, "xn--g2xx48c": _2, "购物": _2, "xn--gckr3f0f": _2, "クラウド": _2, "xn--gk3at1e": _2, "通販": _2, "xn--hxt814e": _2, "网店": _2, "xn--i1b6b1a6a2e": _2, "संगठन": _2, "xn--imr513n": _2, "餐厅": _2, "xn--io0a7i": _2, "网络": _2, "xn--j1aef": _2, "ком": _2, "xn--jlq480n2rg": _2, "亚马逊": _2, "xn--jvr189m": _2, "食品": _2, "xn--kcrx77d1x4a": _2, "飞利浦": _2, "xn--kput3i": _2, "手机": _2, "xn--mgba3a3ejt": _2, "ارامكو": _2, "xn--mgba7c0bbn0a": _2, "العليان": _2, "xn--mgbab2bd": _2, "بازار": _2, "xn--mgbca7dzdo": _2, "ابوظبي": _2, "xn--mgbi4ecexp": _2, "كاثوليك": _2, "xn--mgbt3dhd": _2, "همراه": _2, "xn--mk1bu44c": _2, "닷컴": _2, "xn--mxtq1m": _2, "政府": _2, "xn--ngbc5azd": _2, "شبكة": _2, "xn--ngbe9e0a": _2, "بيتك": _2, "xn--ngbrx": _2, "عرب": _2, "xn--nqv7f": _2, "机构": _2, "xn--nqv7fs00ema": _2, "组织机构": _2, "xn--nyqy26a": _2, "健康": _2, "xn--otu796d": _2, "招聘": _2, "xn--p1acf": [1, { "xn--90amc": _3, "xn--j1aef": _3, "xn--j1ael8b": _3, "xn--h1ahn": _3, "xn--j1adp": _3, "xn--c1avg": _3, "xn--80aaa0cvac": _3, "xn--h1aliz": _3, "xn--90a1af": _3, "xn--41a": _3 }], "рус": [1, { "биз": _3, "ком": _3, "крым": _3, "мир": _3, "мск": _3, "орг": _3, "самара": _3, "сочи": _3, "спб": _3, "я": _3 }], "xn--pssy2u": _2, "大拿": _2, "xn--q9jyb4c": _2, "みんな": _2, "xn--qcka1pmc": _2, "グーグル": _2, "xn--rhqv96g": _2, "世界": _2, "xn--rovu88b": _2, "書籍": _2, "xn--ses554g": _2, "网址": _2, "xn--t60b56a": _2, "닷넷": _2, "xn--tckwe": _2, "コム": _2, "xn--tiq49xqyj": _2, "天主教": _2, "xn--unup4y": _2, "游戏": _2, "xn--vermgensberater-ctb": _2, "vermögensberater": _2, "xn--vermgensberatung-pwb": _2, "vermögensberatung": _2, "xn--vhquv": _2, "企业": _2, "xn--vuq861b": _2, "信息": _2, "xn--w4r85el8fhu5dnra": _2, "嘉里大酒店": _2, "xn--w4rs40l": _2, "嘉里": _2, "xn--xhq521b": _2, "广东": _2, "xn--zfr164b": _2, "政务": _2, "xyz": [1, { "botdash": _3, "telebit": _6 }], "yachts": _2, "yahoo": _2, "yamaxun": _2, "yandex": _2, "yodobashi": _2, "yoga": _2, "yokohama": _2, "you": _2, "youtube": _2, "yun": _2, "zappos": _2, "zara": _2, "zero": _2, "zip": _2, "zone": [1, { "triton": _6, "stackit": _3, "lima": _3 }], "zuerich": _2 }]; return rules2; })(); function lookupInTrie(parts, trie, index, allowedMask) { let result = null; let node = trie; while (node !== void 0) { if ((node[0] & allowedMask) !== 0) { result = { index: index + 1, isIcann: node[0] === 1, isPrivate: node[0] === 2 }; } if (index === -1) { break; } const succ = node[1]; node = Object.prototype.hasOwnProperty.call(succ, parts[index]) ? succ[parts[index]] : succ["*"]; index -= 1; } return result; } function suffixLookup(hostname, options, out) { var _a; if (fast_path_default(hostname, options, out)) { return; } const hostnameParts = hostname.split("."); const allowedMask = (options.allowPrivateDomains ? 2 : 0) | (options.allowIcannDomains ? 1 : 0); const exceptionMatch = lookupInTrie(hostnameParts, exceptions2, hostnameParts.length - 1, allowedMask); if (exceptionMatch !== null) { out.isIcann = exceptionMatch.isIcann; out.isPrivate = exceptionMatch.isPrivate; out.publicSuffix = hostnameParts.slice(exceptionMatch.index + 1).join("."); return; } const rulesMatch = lookupInTrie(hostnameParts, rules, hostnameParts.length - 1, allowedMask); if (rulesMatch !== null) { out.isIcann = rulesMatch.isIcann; out.isPrivate = rulesMatch.isPrivate; out.publicSuffix = hostnameParts.slice(rulesMatch.index).join("."); return; } out.isIcann = false; out.isPrivate = false; out.publicSuffix = (_a = hostnameParts[hostnameParts.length - 1]) !== null && _a !== void 0 ? _a : null; } var RESULT = getEmptyResult(); function parse(url, options = {}) { return parseImpl(url, 5, suffixLookup, options, getEmptyResult()); } function getHostname(url, options = {}) { resetResult(RESULT); return parseImpl(url, 0, suffixLookup, options, RESULT).hostname; } function getPublicSuffix(url, options = {}) { resetResult(RESULT); return parseImpl(url, 2, suffixLookup, options, RESULT).publicSuffix; } function getDomain2(url, options = {}) { resetResult(RESULT); return parseImpl(url, 3, suffixLookup, options, RESULT).domain; } function getSubdomain2(url, options = {}) { resetResult(RESULT); return parseImpl(url, 4, suffixLookup, options, RESULT).subdomain; } function getDomainWithoutSuffix2(url, options = {}) { resetResult(RESULT); return parseImpl(url, 5, suffixLookup, options, RESULT).domainWithoutSuffix; } var import_moment = __toESM(require_moment(), 1); var Database = class _Database extends Dexie$1 { constructor() { super("IwaraDownloadTool"); this.version(2).stores({ follows: "id, username, name, friend, following, followedBy", friends: "id, username, name, friend, following, followedBy", videos: "ID, Type, UploadTime, Private, Unlisted", caches: "ID" }); this.follows = this.table("follows"); this.friends = this.table("friends"); this.videos = this.table("videos"); this.caches = this.table("caches"); } async getFilteredVideos(startTime, endTime) { if (isNullOrUndefined(startTime) || isNullOrUndefined(endTime)) return []; return this.videos.where("UploadTime").between(startTime, endTime, true, true).and((video) => (video.Type === "partial" || video.Type === "full") && (video.Private || video.Unlisted)).and((video) => !isNullOrUndefined(video.RAW)).toArray(); } static getInstance() { if (isNullOrUndefined(_Database.instance)) _Database.instance = new _Database(); return _Database.instance; } static destroyInstance() { _Database.instance = void 0; } }; var db = Database.getInstance(); Date.prototype.format = function(format) { return (0, import_moment.default)(this).format(format); }; var unlimitedFetch = async (input, init = {}, options) => { const { force = false, retry = false, maxRetries = 3, retryDelay = 3e3, successStatus = [200, 201], failStatuses = [403, 404], onFail, onRetry } = options || {}; const successStatuses = Array.isArray(successStatus) ? successStatus : [successStatus]; const failStatusList = Array.isArray(failStatuses) ? failStatuses : [failStatuses]; const url = typeof input === "string" ? input : input.url; const isCrossOrigin = force || new URL(url).hostname !== unsafeWindow.location.hostname; const doFetch = async () => { if (isCrossOrigin) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: init.method, url, headers: init.headers || {}, data: init.body || void 0, onload: (response) => { resolve(new Response(response.responseText, { status: response.status, statusText: response.statusText })); }, onerror: reject }); }); } else { return originalFetch(input, init); } }; if (!retry) return doFetch(); let lastResponse = await doFetch(); let attempts = 1; while (attempts < maxRetries) { if (successStatuses.includes(lastResponse.status)) return lastResponse; if (failStatusList.includes(lastResponse.status)) break; attempts++; if (onRetry) await onRetry(lastResponse); await delay(retryDelay); lastResponse = await doFetch(); } if (onFail) await onFail(lastResponse); return lastResponse; }; var findElement = (element, condition) => { while (!isNullOrUndefined(element) && !element.matches(condition)) { if (isNullOrUndefined(element.parentElement)) return void 0; element = element.parentElement; } return element.querySelectorAll(condition).length > 1 ? void 0 : element; }; var renderNode = (renderCode) => { let code = prune(renderCode); if (isNullOrUndefined(code)) throw new Error("RenderCode null"); if (typeof code === "string") { return document.createTextNode(code.replaceVariable(i18nList[config.language])); } if (renderCode instanceof Node) { return code; } if (typeof renderCode !== "object" || !renderCode.nodeType) { throw new Error("Invalid arguments"); } const { nodeType, attributes, events, className, childs } = renderCode; const node = document.createElement(nodeType); if (!isNullOrUndefined(events) && Object.keys(events).length > 0) { Object.entries(events).forEach(([eventName, eventHandler]) => originalAddEventListener.call(node, eventName, eventHandler)); } if (!isNullOrUndefined(attributes) && Object.keys(attributes).length > 0) { Object.entries(attributes).forEach(([key, value]) => { node.setAttribute(key, value); node[key] = value; }); } if (!isNullOrUndefined(className) && className.length > 0) { node.classList.add(...typeof className === "string" ? [className] : className); } if (!isNullOrUndefined(childs)) { node.append(...(isArray(childs) ? childs : [childs]).filter((child) => !isNullOrUndefined(child)).map(renderNode)); } return node; }; var activeToasts = new Dictionary(); var toastTimeouts = new Map(); var toastIntervals = new Map(); var toastContainers = new Map(); var offscreenContainer = document.createElement("div"); offscreenContainer.classList.add("offscreen-container"); var getContainer = (gravity, position) => { const containerId = `toast-container-${gravity}-${position}`; if (!toastContainers.has(containerId)) { const container = document.createElement("div"); container.id = containerId; container.classList.add("toast-container", `toast-${gravity}`, `toast-${position}`); document.body.appendChild(container); toastContainers.set(containerId, container); } return toastContainers.get(containerId); }; var addTimeout = (toast, callback) => { if (isNullOrUndefined(toast.options.duration)) return; delTimeout(toast); const duration = toast.options.duration; const timeoutId = window.setTimeout(() => { callback(); delTimeout(toast); }, duration); toastTimeouts.set(toast, timeoutId); if (!toast.showProgress) return; if (isNullOrUndefined(toast.progress)) return; const startTime = Date.now(); const updateRemainingTime = () => { if (isNullOrUndefined(toast.progress)) return; const elapsed = Date.now() - startTime; const remaining = Math.max(0, duration - elapsed); toast.progress.style.setProperty("--toast-progress", `${remaining / duration}`); }; toast.progress.style.setProperty("--toast-progress", `1`); const intervalId = window.setInterval(updateRemainingTime, 20); toastIntervals.set(toast, intervalId); }; var delTimeout = (toast) => { const timeoutId = toastTimeouts.get(toast); if (!isNullOrUndefined(timeoutId)) { clearTimeout(timeoutId); toastTimeouts.delete(toast); } if (!toast.showProgress) return; const intervalId = toastIntervals.get(toast); if (!isNullOrUndefined(intervalId)) { clearInterval(intervalId); toastIntervals.delete(toast); } if (!isNullOrUndefined(toast.progress)) { toast.progress.style.removeProperty("--toast-progress"); } }; var Toast = class _Toast { static defaults = { id: UUID(), gravity: "top", position: "left", stopOnFocus: true, oldestFirst: true, showProgress: false }; constructor(options) { this.options = { ..._Toast.defaults, ...options }; this.id = this.options.id; this.root = getContainer(this.options.gravity, this.options.position); this.gravity = this.options.gravity; this.position = this.options.position; this.stopOnFocus = this.options.stopOnFocus; this.oldestFirst = this.options.oldestFirst; this.showProgress = this.options.showProgress; this.element = document.createElement("div"); this.applyBaseStyles().addCloseButton().createContent().ensureCloseMethod().bindEvents(); activeToasts.set(this.id, this); } applyBaseStyles() { this.element.classList.add("toast"); if (this.options.className) { const classes = Array.isArray(this.options.className) ? this.options.className : [this.options.className]; classes.forEach((cls) => this.element.classList.add(cls)); } return this; } createContent() { this.content = document.createElement("div"); this.content.classList.add("toast-content"); if (this.options.text) { this.content.textContent = this.options.text; } if (this.options.node) { this.content.appendChild(this.options.node); } if (this.options.style) { this.applyStyles(this.content, this.options.style); } if (this.options.showProgress) { this.progress = document.createElement("div"); this.progress.classList.add("toast-progress"); this.content.appendChild(this.progress); } this.element.appendChild(this.content); return this; } addCloseButton() { if (this.options.close) { this.closeButton = document.createElement("span"); this.closeButton.className = "toast-close"; this.closeButton.textContent = "🗙"; this.closeButtonHandler = () => this.hide("close-button"); this.closeButton.addEventListener("click", this.closeButtonHandler); this.element.appendChild(this.closeButton); } return this; } setToastRect() { if (!this.element.classList.contains("show")) offscreenContainer.appendChild(this.element); this.element.style.removeProperty("--toast-height"); this.element.style.removeProperty("--toast-width"); this.element.style.setProperty("max-height", "none", "important"); this.element.style.setProperty("max-width", `${this.root.getBoundingClientRect().width}px`, "important"); const { height, width } = this.element.getBoundingClientRect(); this.element.style.setProperty("--toast-height", `${height}px`); this.element.style.setProperty("--toast-width", `${width}px`); this.element.style.removeProperty("max-height"); this.element.style.removeProperty("max-width"); if (!this.element.classList.contains("show")) offscreenContainer.removeChild(this.element); return this; } ensureCloseMethod() { if (isNullOrUndefined(this.options.duration) && isNullOrUndefined(this.options.close) && isNullOrUndefined(this.options.onClick)) { this.options.onClick = () => this.hide("other"); } return this; } bindEvents() { if (this.stopOnFocus && !isNullOrUndefined(this.options.duration) && this.options.duration > 0) { this.mouseOverHandler = () => delTimeout(this); this.mouseLeaveHandler = () => addTimeout(this, () => this.hide("timeout")); this.element.addEventListener("mouseover", this.mouseOverHandler); this.element.addEventListener("mouseleave", this.mouseLeaveHandler); } if (!isNullOrUndefined(this.options.onClick)) { this.clickHandler = this.options.onClick.bind(this); this.element.addEventListener("click", this.clickHandler); } return this; } applyStyles(element, styles) { function camelToKebab(str) { return str.replace(/([A-Z])/g, "-$1").toLowerCase(); } for (const key in styles) { const value = styles[key]; const property = camelToKebab(key); if (isNullOrUndefined(value)) { element.style.removeProperty(property); continue; } const important = value.includes("!important"); const cleanValue = value.replace(/\s*!important\s*/, "").trim(); element.style.setProperty(property, cleanValue, important ? "important" : ""); } } toggleAnimationState(animation) { if (!this.element.classList.replace(animation ? "hide" : "show", animation ? "show" : "hide")) { this.element.classList.add(animation ? "show" : "hide"); } return this; } insertToastElement() { if (this.oldestFirst) { this.root.insertBefore(this.element, this.root.firstChild); } else { if (this.root.lastChild) { this.root.insertBefore(this.element, this.root.lastChild.nextSibling); } else { this.root.appendChild(this.element); } } return this; } setupAutoHide() { if (!isNullOrUndefined(this.options.duration) && this.options.duration > 0) { addTimeout(this, () => this.hide("timeout")); } return this; } show() { this.setToastRect().insertToastElement().toggleAnimationState(true).setupAutoHide(); return this; } showToast() { return this.show(); } removeEventListeners() { if (this.mouseOverHandler) { this.element.removeEventListener("mouseover", this.mouseOverHandler); } if (this.mouseLeaveHandler) { this.element.removeEventListener("mouseleave", this.mouseLeaveHandler); } if (this.clickHandler) { this.element.removeEventListener("click", this.clickHandler); } if (this.options.close && this.closeButton && this.closeButtonHandler) { this.closeButton.removeEventListener("click", this.closeButtonHandler); } return this; } hide(reason = "other") { if (!this.element) return; delTimeout(this); activeToasts.delete(this.id); this.animationEndHandler = (e) => { if (e.animationName.startsWith("toast-out")) { this.element.removeEventListener("animationend", this.animationEndHandler); this.element.remove(); this.options.onClose?.call(this, new CustomEvent("toast-close", { detail: { reason } })); } }; this.element.addEventListener("animationend", this.animationEndHandler); this.removeEventListeners().toggleAnimationState(false); } hideToast() { this.hide("other"); } }; function createToast(options) { return new Toast(options); } globalThis.Toast = createToast; globalThis.Toastify = createToast; (document.body ?? document.documentElement).appendChild(offscreenContainer); window.addEventListener("resize", debounce(() => { for (const [_, toast] of activeToasts) { toast.setToastRect(); } }, 100)); async function refreshToken() { const { authorization } = config; if (!isLoggedIn()) throw new Error(`Refresh token failed: Not logged in`); const refreshToken2 = localStorage.getItem("token") ?? authorization; if (isNullOrUndefined(refreshToken2) || refreshToken2.isEmpty()) { throw new Error(`Refresh token failed: no refresh token`); } const oldAccessToken = localStorage.getItem("accessToken"); try { const res = await unlimitedFetch("https://api.iwara.tv/user/token", { method: "POST", headers: { Authorization: `Bearer ${refreshToken2}` } }); if (!res.ok) { throw new Error(`Refresh token failed with status: ${res.status}`); } const { accessToken } = await res.json(); if (!accessToken) { throw new Error(`No access token in response`); } if (!oldAccessToken || oldAccessToken !== accessToken) { localStorage.setItem("accessToken", accessToken); } return accessToken; } catch (error) { originalConsole.warn("Failed to refresh token:", error); if (!oldAccessToken?.trim()) { throw new Error(`Refresh token failed and no valid access token available`); } return oldAccessToken; } } async function getAuth(url) { return prune({ "Accept": "application/json", "Cooike": unsafeWindow.document.cookie, "Authorization": isLoggedIn() ? `Bearer ${localStorage.getItem("accessToken") ?? await refreshToken()}` : void 0, "X-Version": !isNullOrUndefined(url) && !url.isEmpty() ? await getXVersion(url) : void 0 }); } function checkIsHaveDownloadLink(comment) { if (!config.checkDownloadLink || isNullOrUndefined(comment) || comment.isEmpty()) { return false; } return ["iwara.zip", "pan.baidu", "/s/", "mega.nz", "drive.google.com", "aliyundrive", "uploadgig", "katfile", "storex", "subyshare", "rapidgator", "filebe", "filespace", "mexa.sh", "mexashare", "mx-sh.net", "icerbox", "alfafile", "1drv.ms", "onedrive.", "gofile.io", "workupload.com", "pixeldrain.", "dailyuploads.net", "katfile.com", "fikper.com", "frdl.io", "rg.to", "gigafile.nu"].filter((i) => comment.toLowerCase().includes(i)).any(); } function toastNode(body, title) { return renderNode({ nodeType: "div", childs: [!isNullOrUndefined(title) && !title.isEmpty() ? { nodeType: "h3", childs: `%#appName#% - ${title}` } : { nodeType: "h3", childs: "%#appName#%" }, { nodeType: "p", childs: body }] }); } function getTextNode(node) { return node.nodeType === Node.TEXT_NODE ? node.textContent || "" : node.nodeType === Node.ELEMENT_NODE ? Array.from(node.childNodes).map(getTextNode).join("") : ""; } function newToast(type2, params) { const logFunc = { [ToastType.Warn]: originalConsole.warn, [ToastType.Error]: originalConsole.error, [ToastType.Log]: originalConsole.log, [ToastType.Info]: originalConsole.info }[type2] || originalConsole.log; if (isNullOrUndefined(params)) params = {}; if (!isNullOrUndefined(params.id) && activeToasts.has(params.id)) activeToasts.get(params.id)?.hide(); switch (type2) { case ToastType.Info: params = Object.assign({ duration: 2e3, style: { background: "linear-gradient(-30deg, rgb(0, 108, 215), rgb(0, 180, 255))" } }, params); case ToastType.Warn: params = Object.assign({ duration: -1, style: { background: "linear-gradient(-30deg, rgb(119, 76, 0), rgb(255, 165, 0))" } }, params); break; case ToastType.Error: params = Object.assign({ duration: -1, style: { background: "linear-gradient(-30deg, rgb(108, 0, 0), rgb(215, 0, 0))" } }, params); default: break; } if (!isNullOrUndefined(params.text)) { params.text = params.text.replaceVariable(i18nList[config.language]).toString(); } logFunc((!isNullOrUndefined(params.text) ? params.text : !isNullOrUndefined(params.node) ? getTextNode(params.node) : "undefined").replaceVariable(i18nList[config.language])); return new Toast(params); } function getDownloadPath(videoInfo) { return analyzeLocalPath(config.downloadPath.trim().replaceVariable({ NowTime: new Date(), UploadTime: new Date(videoInfo.UploadTime), AUTHOR: videoInfo.Author, ID: videoInfo.ID, TITLE: videoInfo.Title.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(72), ALIAS: videoInfo.Alias.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(64), QUALITY: videoInfo.DownloadQuality })); } function analyzeLocalPath(path) { try { return new Path(path); } catch (error) { let toast = newToast(ToastType.Error, { node: toastNode([`%#downloadPathError#%`, { nodeType: "br" }, stringify(error)], "%#settingsCheck#%"), position: "center", onClick() { toast.hide(); } }); toast.show(); throw new Error(`%#downloadPathError#% ["${path}"]`); } } async function EnvCheck() { try { if (GM_info.scriptHandler !== "ScriptCat" && GM_info.downloadMode !== "browser") { GM_getValue("isDebug") && originalConsole.debug("[Debug]", GM_info); throw new Error("%#browserDownloadModeError#%"); } } catch (error) { let toast = newToast(ToastType.Error, { node: toastNode([`%#configError#%`, { nodeType: "br" }, stringify(error)], "%#settingsCheck#%"), position: "center", onClick() { toast.hide(); } }); toast.show(); return false; } return true; } async function localPathCheck() { try { let pathTest = analyzeLocalPath(config.downloadPath.replaceVariable({ NowTime: new Date(), UploadTime: new Date(), AUTHOR: "test", ID: "test", TITLE: "test", ALIAS: "test", QUALITY: "test" })); if (isNullOrUndefined(pathTest)) throw "analyzeLocalPath error"; if (pathTest.fullPath.isEmpty()) throw "analyzeLocalPath isEmpty"; } catch (error) { let toast = newToast(ToastType.Error, { node: toastNode([`%#downloadPathError#%`, { nodeType: "br" }, stringify(error)], "%#settingsCheck#%"), position: "center", onClick() { toast.hide(); } }); toast.show(); return false; } return true; } async function aria2Check() { try { let res = await (await unlimitedFetch(config.aria2Path, { method: "POST", headers: { "accept": "application/json", "content-type": "application/json" }, body: JSON.stringify({ "jsonrpc": "2.0", "method": "aria2.tellActive", "id": UUID(), "params": ["token:" + config.aria2Token] }) })).json(); if (res.error) { throw new Error(res.error.message); } } catch (error) { let toast = newToast(ToastType.Error, { node: toastNode([`Aria2 RPC %#connectionTest#%`, { nodeType: "br" }, stringify(error)], "%#settingsCheck#%"), position: "center", onClick() { toast.hide(); } }); toast.show(); return false; } return true; } async function iwaraDownloaderCheck() { try { let res = await (await unlimitedFetch(config.iwaraDownloaderPath, { method: "POST", headers: { "accept": "application/json", "content-type": "application/json" }, body: JSON.stringify(prune({ "ver": GM_getValue("version", "0.0.0").split(".").map((i) => Number(i)), "code": "State", "token": config.iwaraDownloaderToken })) })).json(); if (res.code !== 0) { throw new Error(res.msg); } } catch (error) { let toast = newToast(ToastType.Error, { node: toastNode([`IwaraDownloader RPC %#connectionTest#%`, { nodeType: "br" }, stringify(error)], "%#settingsCheck#%"), position: "center", onClick() { toast.hide(); } }); toast.show(); return false; } return true; } function aria2Download(videoInfo) { (async function(id, author, title, uploadTime, info, tag, quality, alias, downloadUrl) { let localPath = analyzeLocalPath(config.downloadPath.replaceVariable({ NowTime: new Date(), UploadTime: new Date(uploadTime), AUTHOR: author, ID: id, TITLE: title.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replaceEmojis("_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(72), ALIAS: alias, QUALITY: quality }).trim()); downloadUrl.searchParams.set("videoid", id); downloadUrl.searchParams.set("download", localPath.fullName); let params = [[downloadUrl.href], prune({ "all-proxy": config.downloadProxy, "all-proxy-passwd": !config.downloadProxy.isEmpty() ? config.downloadProxyPassword : void 0, "all-proxy-user": !config.downloadProxy.isEmpty() ? config.downloadProxyUsername : void 0, "out": localPath.fullName, "dir": localPath.directory, "referer": window.location.hostname, "header": ["Cookie:" + unsafeWindow.document.cookie] })]; let res = await aria2API("aria2.addUri", params); originalConsole.log(`Aria2 ${title} ${JSON.stringify(res)}`); newToast(ToastType.Info, { gravity: "bottom", node: toastNode(`${videoInfo.Title}[${videoInfo.ID}] %#pushTaskSucceed#%`) }).show(); })(videoInfo.ID, videoInfo.Author, videoInfo.Title, videoInfo.UploadTime, videoInfo.Comments, videoInfo.Tags, videoInfo.DownloadQuality, videoInfo.Alias, videoInfo.DownloadUrl.toURL()); } function iwaraDownloaderDownload(videoInfo) { (async function(videoInfo2) { let r = await (await unlimitedFetch(config.iwaraDownloaderPath, { method: "POST", headers: { "accept": "application/json", "content-type": "application/json" }, body: JSON.stringify(prune({ "ver": GM_getValue("version", "0.0.0").split(".").map((i) => Number(i)), "code": "add", "token": config.iwaraDownloaderToken, "data": { "info": { "title": videoInfo2.Title, "url": videoInfo2.DownloadUrl, "size": videoInfo2.Size, "source": videoInfo2.ID, "alias": videoInfo2.Alias, "author": videoInfo2.Author, "uploadTime": videoInfo2.UploadTime, "comments": videoInfo2.Comments, "tags": videoInfo2.Tags, "path": config.downloadPath.replaceVariable({ NowTime: new Date(), UploadTime: videoInfo2.UploadTime, AUTHOR: videoInfo2.Author, ID: videoInfo2.ID, TITLE: videoInfo2.Title, ALIAS: videoInfo2.Alias, QUALITY: videoInfo2.DownloadQuality }) }, "option": { "proxy": config.downloadProxy, "cookies": unsafeWindow.document.cookie } } })) })).json(); if (r.code === 0) { originalConsole.log(`${videoInfo2.Title} %#pushTaskSucceed#% ${r}`); newToast(ToastType.Info, { node: toastNode(`${videoInfo2.Title}[${videoInfo2.ID}] %#pushTaskSucceed#%`) }).show(); } else { let toast = newToast(ToastType.Error, { node: toastNode([`${videoInfo2.Title}[${videoInfo2.ID}] %#pushTaskFailed#% `, { nodeType: "br" }, r.msg], "%#iwaraDownloaderDownload#%"), onClick() { toast.hide(); } }); toast.show(); } })(videoInfo); } function othersDownload(videoInfo) { (async function(DownloadUrl) { DownloadUrl.searchParams.set("download", getDownloadPath(videoInfo).fullName); GM_openInTab(DownloadUrl.href, { active: false, insert: true, setParent: true }); })(videoInfo.DownloadUrl.toURL()); } function browserDownloadErrorParse(error) { let errorInfo = stringify(error); if (!(error instanceof Error)) { errorInfo = { "not_enabled": `%#browserDownloadNotEnabled#%`, "not_whitelisted": `%#browserDownloadNotWhitelisted#%`, "not_permitted": `%#browserDownloadNotPermitted#%`, "not_supported": `%#browserDownloadNotSupported#%`, "not_succeeded": `%#browserDownloadNotSucceeded#% ${isNullOrUndefined(error.details) ? "UnknownError" : error.details}` }[error.error] || `%#browserDownloadUnknownError#%`; } return errorInfo; } function browserDownload(videoInfo) { (async function(ID, Author, Title, UploadTime, Info, Tag, DownloadQuality, Alias, DownloadUrl) { function toastError(error) { let toast = newToast(ToastType.Error, { node: toastNode([`${Title}[${ID}] %#downloadFailed#%`, { nodeType: "br" }, browserDownloadErrorParse(error), { nodeType: "br" }, `%#tryRestartingDownload#%`], "%#browserDownload#%"), async onClick() { toast.hide(); await pushDownloadTask(videoInfo); } }); toast.show(); } GM_download({ url: DownloadUrl, saveAs: false, name: getDownloadPath(videoInfo).fullPath, onerror: (err) => toastError(err), ontimeout: () => toastError(new Error("%#browserDownloadTimeout#%")) }); })(videoInfo.ID, videoInfo.Author, videoInfo.Title, videoInfo.UploadTime, videoInfo.Comments, videoInfo.Tags, videoInfo.DownloadQuality, videoInfo.Alias, videoInfo.DownloadUrl); } async function aria2API(method, params) { return await (await unlimitedFetch(config.aria2Path, { headers: { "accept": "application/json", "content-type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", method, id: UUID(), params: [`token:${config.aria2Token}`, ...params] }), method: "POST" })).json(); } function aria2TaskExtractVideoID(task2) { try { if (isNullOrUndefined(task2.files) || task2.files.length !== 1) return; const file = task2.files[0]; if (isNullOrUndefined(file)) return; if (file.uris.length < 1) return; let downloadUrl = file.uris[0].uri.toURL(); if (isNullOrUndefined(downloadUrl)) return; let videoID; if (downloadUrl.searchParams.has("videoid")) videoID = downloadUrl.searchParams.get("videoid"); if (!isNullOrUndefined(videoID) && !videoID.isEmpty()) return videoID; if (isNullOrUndefined(file.path) || file.path.isEmpty()) return; let path = analyzeLocalPath(file.path); if (isNullOrUndefined(path.fullName) || path.fullName.isEmpty()) return; videoID = path.fullName.toLowerCase().among("[", "].mp4", false, true); if (videoID.isEmpty()) return; return videoID; } catch (error) { GM_getValue("isDebug") && originalConsole.debug(`[Debug] check aria2 task file fail! ${stringify(task2)}`); return; } } async function aria2TaskCheckAndRestart() { let stoped = prune((await aria2API("aria2.tellStopped", [0, 4096, ["gid", "status", "files", "errorCode", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => { let ID = aria2TaskExtractVideoID(task2); if (!isNullOrUndefined(ID) && !ID.isEmpty()) { return { id: ID, data: task2 }; } })); let active = prune((await aria2API("aria2.tellActive", [["gid", "status", "files", "downloadSpeed", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => { let ID = aria2TaskExtractVideoID(task2); if (!isNullOrUndefined(ID) && !ID.isEmpty()) { return { id: ID, data: task2 }; } })); let downloadNormalTasks = active.filter((task2) => isConvertibleToNumber(task2.data.downloadSpeed) && Number(task2.data.downloadSpeed) >= 512).unique("id"); let downloadCompleted = stoped.filter((task2) => task2.data.status === "complete").unique("id"); let downloadUncompleted = stoped.difference(downloadCompleted, "id").difference(downloadNormalTasks, "id"); let downloadToSlowTasks = active.filter((task2) => isConvertibleToNumber(task2.data.downloadSpeed) && Number(task2.data.downloadSpeed) <= 512).unique("id"); let needRestart = downloadUncompleted.union(downloadToSlowTasks, "id"); if (needRestart.length !== 0) { newToast(ToastType.Warn, { id: "aria2TaskCheckAndRestart", node: toastNode([`发现 ${needRestart.length} 个需要重启的下载任务!`, { nodeType: "br" }, "%#tryRestartingDownload#%"], "%#aria2TaskCheck#%"), async onClick() { this.hide(); for (let i = 0; i < needRestart.length; i++) { const task2 = needRestart[i]; await pushDownloadTask(await parseVideoInfo({ Type: "init", ID: task2.id }), true); let activeTasks = active.filter((activeTask) => activeTask.id === task2.id); for (let t = 0; t < activeTasks.length; t++) { const element = activeTasks[t]; await aria2API("aria2.forceRemove", [element.data.gid]); } } } }).show(); } else { newToast(ToastType.Info, { id: "aria2TaskCheckAndRestart", duration: 1e4, node: toastNode(`未发现需要重启的下载任务!`) }).show(); } } function getPlayload(authorization) { return JSON.parse(decodeURIComponent(encodeURIComponent(window.atob(authorization.split(" ").pop().split(".")[1])))); } async function check() { if (await localPathCheck()) { switch (config.downloadType) { case DownloadType.Aria2: return await aria2Check(); case DownloadType.IwaraDownloader: return await iwaraDownloaderCheck(); case DownloadType.Browser: return await EnvCheck(); default: break; } return true; } else { return false; } } async function getXVersion(urlString) { let url = urlString.toURL(); const data = new TextEncoder().encode([url.pathname.split("/").pop(), url.searchParams.get("expires"), "5nFp9kmbNnHdAFhaqMvt"].join("_")); const hashBuffer = await crypto.subtle.digest("SHA-1", data); return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join(""); } var main_default = '@keyframes rainbow-horizontal{0%{background-position:0% 0%}to{background-position:200% 0%}}@keyframes rainbow-vertical{0%{background-position:0% 0%}to{background-position:0% 200%}}.rainbow-text{background-image:linear-gradient(to right,#ff4040,#ffff40,#40ff40,#40ffff,#4040ff,#ff40ff,#ff4040);background-size:200% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:rainbow-horizontal .8s infinite linear;font-weight:700}#pluginMenu{z-index:2147483644;position:fixed;top:50%;right:0;padding:10px 26px;background-color:var(--body-dark);border:1px solid var(--text);border-radius:5px;box-shadow:0 0 10px var(--text);transform:translate(calc(100% - 26px)) translateY(-50%);transition:transform .3s ease-in-out}#pluginMenu:not(.expanded){overflow:visible}#pluginMenu:not(.expanded):before{content:"";mask:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIj48cGF0aCBkPSJNNTYwLTI0MCAzMjAtNDgwbDI0MC0yNDAgNTYgNTYtMTg0IDE4NCAxODQgMTg0LTU2IDU2WiIvPjwvc3ZnPg==) no-repeat center;background-color:var(--text);width:24px;height:24px;position:absolute;left:0;top:50%;line-height:0;transform:translateY(-50%)}#pluginMenu.expanded{transform:translate(0) translateY(-50%)}#pluginMenu ul{list-style:none;margin:0;padding:0}#pluginMenu li{padding:5px 10px;cursor:pointer;text-align:center;user-select:none;color:var(--text)}#pluginMenu li:hover{background-color:var(--primary-dark);border-radius:3px}#pluginConfig{color:var(--text);position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000000bf;z-index:2147483646;display:flex;flex-direction:column;align-items:center;justify-content:center}#pluginConfig .main{background-color:var(--body);padding:24px;margin:10px;overflow-y:auto;width:480px}#pluginConfig .buttonList{display:flex;flex-direction:row;justify-content:center}@media (max-width: 640px){#pluginConfig .main{width:100%}}#pluginConfig button{background-color:var(--primary);margin:0 20px;padding:10px 20px;color:var(--primary-text);font-size:18px;border:none;border-radius:4px;cursor:pointer}#pluginConfig button{background-color:var(--primary)}#pluginConfig button[disabled]{background-color:var(--muted);cursor:not-allowed}#pluginConfig p{display:flex;flex-direction:column;margin-top:10px;margin-bottom:0}#pluginConfig fieldset{border:none;margin:10px 0 0;padding:0;display:flex;justify-content:space-between;flex-wrap:nowrap}#pluginConfig fieldset>legend{margin:0 0 5px;padding:0}#pluginConfig fieldset>label{text-align:center}#pluginConfig p label{display:flex;flex-direction:column;margin:5px 0 0}#pluginConfig .inputRadioLine{display:flex;align-items:center;flex-direction:row;justify-content:space-between}#pluginConfig input[type=text],#pluginConfig input[type=password]{outline:none;border-top:none;border-right:none;border-left:none;border-image:initial;border-bottom:1px solid var(--muted);line-height:1;height:30px;box-sizing:border-box;width:100%;background-color:var(--body);color:var(--text)}#pluginConfig input[type=checkbox].switch{outline:none;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;width:40px;height:20px;background:var(--muted);border-radius:10px;transition:border-color .2s,background-color .2s}#pluginConfig input[type=checkbox].switch:after{content:"";display:inline-block;width:40%;height:80%;border-radius:50%;background:var(--white);box-shadow:0,0,2px,var(--muted);transition:.2s;top:2px;position:absolute;right:55%}#pluginConfig input[type=checkbox].switch:checked{background:var(--success)}#pluginConfig input[type=checkbox].switch:checked:after{content:"";position:absolute;right:2px;top:2px}#pluginOverlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000000bf;z-index:2147483645;display:flex;flex-direction:column;align-items:center;justify-content:center}#pluginOverlay .main{color:var(--text);font-size:24px;width:60%;background-color:#404040bf;padding:24px;margin:10px;overflow-y:auto}@media (max-width: 640px){#pluginOverlay .main{width:100%}}#pluginOverlay button{padding:10px 20px;color:var(--primary-text);font-size:18px;border:none;border-radius:4px;cursor:pointer}#pluginOverlay button{background-color:var(--primary)}#pluginOverlay button[disabled]{background-color:var(--muted);cursor:not-allowed}#pluginOverlay .checkbox{width:32px;height:32px;margin:0 4px 0 0;padding:0}#pluginOverlay .checkbox-container{display:flex;align-items:center;margin:0 0 10px}#pluginOverlay .checkbox-label{color:var(--text);font-size:32px;font-weight:700;margin-left:10px;display:flex;align-items:center}.fixed-bottom-right{position:fixed;bottom:0;right:0;background-color:var(--body);color:var(--text);border-top:1px solid var(--primary);border-left:1px solid var(--primary);border-top-left-radius:6px;padding:2px 5px;margin:0;user-select:none;z-index:102}.follow{bottom:24px;right:2px;border-radius:2px;position:absolute;padding:3px 5px;background-color:#000c;pointer-events:none}.selectButton{accent-color:var(--primary);position:absolute;width:38px;height:38px;right:0;cursor:pointer;z-index:102;top:22px}.deleteButton{accent-color:var(--danger);position:absolute;width:38px;height:38px;left:0;cursor:pointer;z-index:101;border:none;padding:0;margin:3px;top:22px}.toast h3{margin:0 0 10px}.toast p{margin:0}.offscreen-container{position:absolute;visibility:hidden;pointer-events:none;max-width:480px}.toast-container{isolation:isolate;position:fixed;z-index:2147483647;display:flex;flex-direction:column;box-sizing:border-box;transition:transform calc(.6 * var(--toast-rate) * 1s) ease,opacity calc(.6 * var(--toast-rate) * 1s) ease}.toast-container.toast-top{top:0}.toast-container.toast-bottom{bottom:0}.toast-container.toast-left{left:0;align-items:flex-start}.toast-container.toast-center{left:50%;transform:translate(-50%);align-items:center}.toast-container.toast-right{right:0;align-items:flex-end}#toast-container-top-left .toast{margin:10px 0 0 10px;transform-origin:left center}#toast-container-top-center .toast{margin:10px 0 0;transform-origin:top}#toast-container-top-right .toast{margin:10px 10px 0 0;transform-origin:right center}#toast-container-bottom-left .toast{margin:0 0 10px 10px;transform-origin:left center}#toast-container-bottom-center .toast{margin:0 0 10px;transform-origin:bottom}#toast-container-bottom-right .toast{margin:0 10px 10px 0;transform-origin:right center}.toast{--toast-rate: 1;--toast-translate: 0;--toast-scale: 1;position:relative;transition:transform calc(.4s * var(--toast-rate)) cubic-bezier(.34,1.56,.64,1),opacity calc(.3s * var(--toast-rate)) ease;transform:translate3d(0,var(--toast-translate),0) scale(var(--toast-scale));max-width:480px;max-height:0px;will-change:transform,opacity;backface-visibility:hidden;contain:content;border-radius:6px;box-shadow:0 4px 8px #00000040}.toast-close{position:absolute;color:var(--text);top:5px;right:5px;cursor:pointer;font-size:12px;line-height:12px;z-index:2147483648;transform-origin:center center}.toast-content{border-radius:6px;padding:14px 18px;max-width:100%;box-sizing:border-box;background:var(--primary);color:var(--primary-text);cursor:pointer;white-space:normal;word-break:break-all;overflow:hidden;position:relative}.toast-progress{position:absolute;bottom:0;left:0;right:0;height:4px;background:#fffc;transform:scaleX(var(--toast-progress, 0));transition:transform calc(.05s * var(--toast-rate)) linear;will-change:transform;backface-visibility:hidden}.toast:hover{z-index:2147483648;--toast-scale: 1.15}.toast-container.toast-left .toast .toast-content .toast-progress{transform-origin:left}.toast-container.toast-center .toast .toast-content .toast-progress{transform-origin:center}.toast-container.toast-right .toast .toast-content .toast-progress{transform-origin:right}.toast-container.toast-top .toast.show{animation:toast-in-top calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-bottom .toast.show{animation:toast-in-bottom calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-top .toast.hide{animation:toast-out-top calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-bottom .toast.hide{animation:toast-out-bottom calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}@keyframes toast-in-top{0%{opacity:0;max-height:0px}to{max-height:var(--toast-height)}}@keyframes toast-in-bottom{0%{opacity:0;max-height:0px}to{max-height:var(--toast-height)}}@keyframes toast-out-top{0%{max-height:var(--toast-height)}to{opacity:0;max-height:0px}}@keyframes toast-out-bottom{0%{max-height:var(--toast-height)}to{opacity:0;max-height:0px}}\n'; var officialWhiteList = ["iwara.tv", "iwara.zip", "iwara.shop"]; var domain = getDomain2(unsafeWindow.location.href) ?? ""; if (!officialWhiteList.includes(domain) && unsafeWindow.location.hostname.includes("iwara")) { XMLHttpRequest.prototype.open = void 0; unsafeWindow.fetch = void 0; unsafeWindow.WebSocket = void 0; if (!confirm(stringify(i18nList[config.language].notOfficialWarning))) { unsafeWindow.location.href = "about:blank"; unsafeWindow.close(); } else { throw "Not official"; } } if (domain !== "iwara.tv") { throw "Not target"; } var isPageType = (type2) => new Set(Object.values(PageType)).has(type2); var isLoggedIn = () => !(unsafeWindow.localStorage.getItem("token") ?? "").isEmpty(); var rating = () => localStorage.getItem("rating") ?? "all"; var mouseTarget = null; async function getCommentData(id, commentID, page = 0) { return await (await unlimitedFetch(`https://api.iwara.tv/video/${id}/comments?page=${page}${!isNullOrUndefined(commentID) && !commentID.isEmpty() ? "&parent=" + commentID : ""}`, { headers: await getAuth() })).json(); } async function getCommentDatas(id, commentID) { let comments = []; let base = await getCommentData(id, commentID); comments.push(...base.results); for (let page = 1; page < Math.ceil(base.count / base.limit); page++) { comments.push(...(await getCommentData(id, commentID, page)).results); } let replies = []; for (let index = 0; index < comments.length; index++) { const comment = comments[index]; if (comment.numReplies > 0) { replies.push(...await getCommentDatas(id, comment.id)); } } comments.push(...replies); return comments; } async function getCDNCache(id, info) { let cache = (await db.videos.where("ID").equals(id).toArray()).pop() ?? info; let cdnCache = await db.caches.where("ID").equals(id).toArray(); if (!cdnCache.any() && (cache?.Type === "partial" || cache?.Type === "full")) { let query = prune({ author: cache.Alias ?? cache.Author, title: cache.Title }); for (const key in query) { let dom = new DOMParser().parseFromString(await (await unlimitedFetch(`https://mmdfans.net/?query=${encodeURIComponent(`${key}:${query[key]}`)}`)).text(), "text/html"); for (let i of [...dom.querySelectorAll(".mdui-col > a")]) { let ID = i.querySelector(".mdui-grid-tile > img")?.src?.toURL()?.pathname?.split("/")?.pop()?.trimTail(".jpg"); if (isNullOrUndefined(ID)) continue; await db.caches.put({ ID, href: `https://mmdfans.net${i.getAttribute("href")}` }); } } } cdnCache = await db.caches.where("ID").equals(id).toArray(); if (cdnCache.any()) { newToast(ToastType.Warn, { node: toastNode([`${cache?.RAW?.title}[${id}] %#parsingFailed#%`, { nodeType: "br" }, `%#cdnCacheFinded#%`], "%#createTask#%"), onClick() { GM_openInTab(cdnCache[0].href, { active: false, insert: true, setParent: true }); this.hide(); } }).show(); return; } newToast(ToastType.Error, { node: toastNode([`${cache?.RAW?.title}[${id}] %#parsingFailed#%`], "%#createTask#%"), onClick() { this.hide(); } }).show(); } async function parseVideoInfo(info) { let ID = info.ID; let Type = info.Type; let RAW = info.RAW; try { switch (info.Type) { case "cache": RAW = info.RAW; ID = RAW.id; Type = "partial"; break; case "init": case "fail": case "partial": case "full": let sourceResult = await (await unlimitedFetch(`https://api.iwara.tv/video/${info.ID}`, { headers: await getAuth() }, { retry: true, maxRetries: 3, failStatuses: [403, 404], retryDelay: 1e3, onRetry: async () => { await refreshToken(); } })).json(); if (isNullOrUndefined(sourceResult.id)) { Type = "fail"; return { ID, Type, RAW, Msg: sourceResult.message ?? stringify(sourceResult) }; } RAW = sourceResult; ID = RAW.id; Type = "full"; break; default: Type = "fail"; return { ID, Type, RAW, Msg: "Unknown type" }; } } catch (error) { newToast(ToastType.Error, { node: toastNode([`${info.RAW?.title}[${ID}] %#parsingFailed#%`], "%#createTask#%"), async onClick() { await parseVideoInfo({ Type: "init", ID, RAW, UploadTime: 0 }); this.hide(); } }).show(); Type = "fail"; return { ID, Type, RAW, Msg: stringify(error) }; } let FileName; let Size; let External; let ExternalUrl; let Description; let DownloadQuality; let DownloadUrl; let Comments; let UploadTime; let Title; let Tags; let Liked; let Alias; let Author; let AuthorID; let Private; let Unlisted; let Following; let Friend; UploadTime = new Date(RAW.createdAt ?? 0).getTime(); Title = RAW.title; Tags = RAW.tags; Liked = RAW.liked; Alias = RAW.user.name; Author = RAW.user.username; AuthorID = RAW.user.id; Private = RAW.private; Unlisted = RAW.unlisted; External = !isNullOrUndefined(RAW.embedUrl) && !RAW.embedUrl.isEmpty(); ExternalUrl = RAW.embedUrl; if (External) { Type = "fail"; return { Type, RAW, ID, Alias, Author, AuthorID, Private, UploadTime, Title, Tags, Liked, External, ExternalUrl, Description, Unlisted, Msg: "external Video" }; } try { switch (Type) { case "full": Following = RAW.user.following; Friend = RAW.user.friend; if (Following) { db.follows.put(RAW.user, AuthorID); } else { db.follows.delete(AuthorID); } if (Friend) { db.friends.put(RAW.user, AuthorID); } else { db.friends.delete(AuthorID); } Description = RAW.body; FileName = RAW.file.name; Size = RAW.file.size; let VideoFileSource = (await (await unlimitedFetch(RAW.fileUrl, { headers: await getAuth(RAW.fileUrl) })).json()).sort((a, b) => (!isNullOrUndefined(config.priority[b.name]) ? config.priority[b.name] : 0) - (!isNullOrUndefined(config.priority[a.name]) ? config.priority[a.name] : 0)); if (isNullOrUndefined(VideoFileSource) || !(VideoFileSource instanceof Array) || VideoFileSource.length < 1) throw new Error(i18nList[config.language].getVideoSourceFailed.toString()); DownloadQuality = config.checkPriority ? config.downloadPriority : VideoFileSource[0].name; let fileList = VideoFileSource.filter((x) => x.name === DownloadQuality); if (!fileList.any()) throw new Error(i18nList[config.language].noAvailableVideoSource.toString()); let Source = fileList[Math.floor(Math.random() * fileList.length)].src.download; if (isNullOrUndefined(Source) || Source.isEmpty()) throw new Error(i18nList[config.language].videoSourceNotAvailable.toString()); DownloadUrl = decodeURIComponent(`https:${Source}`); Comments = `${(await getCommentDatas(ID)).map((i) => i.body).join("\n")}`.normalize("NFKC"); return { Type, RAW, ID, Alias, Author, AuthorID, Private, UploadTime, Title, Tags, Liked, External, FileName, DownloadQuality, ExternalUrl, Description, Comments, DownloadUrl, Size, Following, Unlisted, Friend }; case "partial": return { Type, RAW, ID, Alias, Author, AuthorID, UploadTime, Title, Tags, Liked, External, ExternalUrl, Unlisted, Private }; default: Type = "fail"; return { Type, RAW, ID, Alias, Author, AuthorID, Private, UploadTime, Title, Tags, Liked, External, ExternalUrl, Description, Unlisted, Msg: "Unknown type" }; } } catch (error) { Type = "fail"; return { Type, RAW, ID, Alias, Author, AuthorID, Private, UploadTime, Title, Tags, Liked, External, ExternalUrl, Description, Unlisted, Msg: stringify(error) }; } } var configEdit = class { constructor(config2) { this.target = config2; this.target.configChange = (item) => { this.configChange.call(this, item); }; this.interfacePage = renderNode({ nodeType: "p" }); let save = renderNode({ nodeType: "button", childs: "%#save#%", attributes: { title: i18nList[config2.language].save }, events: { click: async () => { save.disabled = !save.disabled; if (await check()) { unsafeWindow.location.reload(); } save.disabled = !save.disabled; } } }); let reset = renderNode({ nodeType: "button", childs: "%#reset#%", attributes: { title: i18nList[config2.language].reset }, events: { click: () => { GM_setValue("isFirstRun", true); unsafeWindow.location.reload(); } } }); this.interface = renderNode({ nodeType: "div", attributes: { id: "pluginConfig" }, childs: [{ nodeType: "div", className: "main", childs: [{ nodeType: "h2", childs: "%#appName#%" }, { nodeType: "label", childs: ["%#language#% ", { nodeType: "input", className: "inputRadioLine", attributes: { name: "language", type: "text", value: this.target.language }, events: { change: (event) => { this.target.language = event.target.value; } } }] }, this.downloadTypeSelect(), this.interfacePage, this.switchButton("checkPriority"), this.switchButton("checkDownloadLink"), this.switchButton("autoFollow"), this.switchButton("autoLike"), this.switchButton("autoInjectCheckbox"), this.switchButton("autoDownloadMetadata"), this.switchButton("autoCopySaveFileName"), this.switchButton("addUnlistedAndPrivate"), this.switchButton("experimentalFeatures"), this.switchButton("enableUnsafeMode"), this.switchButton("isDebug", GM_getValue, (name, e) => { GM_setValue(name, e.target.checked); unsafeWindow.location.reload(); }, false)] }, { nodeType: "p", className: "buttonList", childs: [reset, save] }] }); } switchButton(name, get, set, defaultValue) { return renderNode({ nodeType: "p", className: "inputRadioLine", childs: [{ nodeType: "label", childs: `%#${name}#%`, attributes: { for: name } }, { nodeType: "input", className: "switch", attributes: { type: "checkbox", name, checked: get !== void 0 ? get(name, defaultValue) : this.target[name] ?? defaultValue ?? false }, events: { change: (e) => { if (set !== void 0) { set(name, e); return; } else { this.target[name] = e.target.checked; } } } }] }); } inputComponent(name, type2, help, get, set) { return renderNode({ nodeType: "label", childs: [{ nodeType: "span", childs: [`%#${name}#%`, help] }, { nodeType: "input", attributes: { name, type: type2 ?? "text", value: get !== void 0 ? get(name) : this.target[name] }, events: { change: (e) => { if (set !== void 0) { set(name, e); return; } else { this.target[name] = e.target.value; } } } }] }); } downloadTypeSelect() { return renderNode({ nodeType: "fieldset", childs: [{ nodeType: "legend", childs: "%#downloadType#%" }, ...Object.keys(DownloadType).filter((i) => isNaN(Number(i))).map((type2, index) => renderNode({ nodeType: "label", childs: [{ nodeType: "input", attributes: { type: "radio", name: "downloadType", value: index, checked: index === Number(this.target.downloadType) }, events: { change: (e) => { this.target.downloadType = Number(e.target.value); } } }, type2] }))] }); } configChange(item) { switch (item) { case "downloadType": const radios = this.interface.querySelectorAll(`[name=${item}]`); radios.forEach((radio) => { radio.checked = Number(radio.value) === Number(this.target.downloadType); }); this.pageChange(); break; case "checkPriority": this.pageChange(); break; default: let element = this.interface.querySelector(`[name=${item}]`); if (element) { switch (element.type) { case "radio": element.value = this.target[item]; break; case "checkbox": element.checked = this.target[item]; break; case "text": case "password": element.value = this.target[item]; break; default: break; } } break; } } pageChange() { while (this.interfacePage.hasChildNodes()) { this.interfacePage.removeChild(this.interfacePage.firstChild); } let downloadConfigInput = [this.inputComponent("downloadPath", "text", renderNode({ nodeType: "a", childs: "%#variable#%", className: "rainbow-text", attributes: { style: "float: inline-end;", href: "https://github.com/dawn-lc/IwaraDownloadTool/wiki/路径可用变量" } }))]; let proxyConfigInput = [this.inputComponent("downloadProxy"), this.inputComponent("downloadProxyUsername"), this.inputComponent("downloadProxyPassword", "password")]; let aria2ConfigInput = [this.inputComponent("aria2Path"), this.inputComponent("aria2Token", "password"), ...proxyConfigInput]; let iwaraDownloaderConfigInput = [this.inputComponent("iwaraDownloaderPath"), this.inputComponent("iwaraDownloaderToken", "password"), ...proxyConfigInput]; switch (this.target.downloadType) { case DownloadType.Aria2: downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); aria2ConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; case DownloadType.IwaraDownloader: downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); iwaraDownloaderConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; default: downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; } if (this.target.checkPriority) { originalNodeAppendChild.call(this.interfacePage, this.inputComponent("downloadPriority")); } } inject() { if (!unsafeWindow.document.querySelector("#pluginConfig")) { originalNodeAppendChild.call(unsafeWindow.document.body, this.interface); this.configChange("downloadType"); } } }; var menu = class { constructor() { let body = new Proxy(this, { set: (target, prop, value) => { if (prop === "pageType") { if (isNullOrUndefined(value) || this.pageType === value) return true; target[prop] = value; this.pageChange(); GM_getValue("isDebug") && originalConsole.debug(`[Debug] Page change to ${this.pageType}`); return true; } return target[prop] = value; } }); body.interfacePage = renderNode({ nodeType: "ul" }); body.interface = renderNode({ nodeType: "div", attributes: { id: "pluginMenu" }, childs: body.interfacePage }); let mouseoutTimer = null; originalAddEventListener.call(body.interface, "mouseover", (event) => { if (mouseoutTimer !== null) { clearTimeout(mouseoutTimer); mouseoutTimer = null; } body.interface.classList.add("expanded"); }); originalAddEventListener.call(body.interface, "mouseout", (event) => { const e = event; const relatedTarget = e.relatedTarget; if (relatedTarget && body.interface.contains(relatedTarget)) { return; } mouseoutTimer = setTimeout(() => { body.interface.classList.remove("expanded"); mouseoutTimer = null; }, 300); }); originalAddEventListener.call(body.interface, "click", (event) => { if (event.target === body.interface) { body.interface.classList.toggle("expanded"); } }); body.observer = new MutationObserver((mutationsList) => body.pageType = getPageType(mutationsList) ?? body.pageType); body.pageType = PageType.Page; return body; } button(name, click) { return renderNode({ nodeType: "li", childs: `%#${name}#%`, events: { click: (event) => { !isNullOrUndefined(click) && click(name, event); event.stopPropagation(); return false; } } }); } async parseUnlistedAndPrivate() { if (!isLoggedIn()) return; const lastMonthTimestamp = Date.now() - 30 * 24 * 60 * 60 * 1e3; const thisMonthUnlistedAndPrivateVideos = await db.videos.where("UploadTime").between(lastMonthTimestamp, Infinity).and((i) => !isInitVideoInfo(i) && !isFailVideoInfo(i) && !isCacheVideoInfo(i) && (i.Private || i.Unlisted)).toArray(); let parseUnlistedAndPrivateVideos = []; let pageCount = 0; const MAX_FIND_PAGES = 64; GM_getValue("isDebug") && originalConsole.debug(`[Debug] Starting fetch loop. MAX_PAGES=${MAX_FIND_PAGES}`); while (pageCount < MAX_FIND_PAGES) { GM_getValue("isDebug") && originalConsole.debug(`[Debug] Fetching page ${pageCount}.`); const response = await unlimitedFetch(`https://api.iwara.tv/videos?subscribed=true&limit=50&rating=${rating()}&page=${pageCount}`, { method: "GET", headers: await getAuth() }, { retry: true, retryDelay: 1e3, onRetry: async () => { await refreshToken(); } }); GM_getValue("isDebug") && originalConsole.debug("[Debug] Received response, parsing JSON."); const data = (await response.json()).results; GM_getValue("isDebug") && originalConsole.debug(`[Debug] Page ${pageCount} returned ${data.length} videos.`); data.forEach((info) => info.user.following = true); const videoPromises = data.map((info) => parseVideoInfo({ Type: "cache", ID: info.id, RAW: info })); GM_getValue("isDebug") && originalConsole.debug("[Debug] Initializing VideoInfo promises."); const videoInfos = await Promise.all(videoPromises); parseUnlistedAndPrivateVideos.push(...videoInfos); let test = videoInfos.filter((i) => i.Type === "partial" && (i.Private || i.Unlisted)).any(); GM_getValue("isDebug") && originalConsole.debug("[Debug] All VideoInfo objects initialized."); if (test && thisMonthUnlistedAndPrivateVideos.intersect(videoInfos, "ID").any()) { GM_getValue("isDebug") && originalConsole.debug(`[Debug] Found private video on page ${pageCount}.`); break; } GM_getValue("isDebug") && originalConsole.debug(`[Debug] Latest private video not found on page ${pageCount}, continuing.`); pageCount++; GM_getValue("isDebug") && originalConsole.debug(`[Debug] Incremented page to ${pageCount}, delaying next fetch.`); await delay(100); } GM_getValue("isDebug") && originalConsole.debug("[Debug] Fetch loop ended. Start updating the database"); const toUpdate = parseUnlistedAndPrivateVideos.difference((await db.videos.where("ID").anyOf(parseUnlistedAndPrivateVideos.map((v) => v.ID)).toArray()).filter((v) => v.Type === "full"), "ID"); if (toUpdate.any()) { GM_getValue("isDebug") && originalConsole.debug(`[Debug] Need to update ${toUpdate.length} pieces of data.`); await db.videos.bulkPut(toUpdate); GM_getValue("isDebug") && originalConsole.debug(`[Debug] Update Completed.`); } else { GM_getValue("isDebug") && originalConsole.debug(`[Debug] No need to update data.`); } } async pageChange() { while (this.interfacePage.hasChildNodes()) { this.interfacePage.removeChild(this.interfacePage.firstChild); } let manualDownloadButton = this.button("manualDownload", (name, event) => { addDownloadTask(); }); let settingsButton = this.button("settings", (name, event) => { editConfig.inject(); }); let exportConfigButton = this.button("exportConfig", (name, event) => { GM_setClipboard(stringify(config)); newToast(ToastType.Info, { node: toastNode(i18nList[config.language].exportConfigSucceed), duration: 3e3, gravity: "bottom", position: "center", onClick() { this.hide(); } }).show(); }); let baseButtons = [manualDownloadButton, exportConfigButton, settingsButton]; let injectCheckboxButton = this.button("injectCheckbox", (name, event) => { if (unsafeWindow.document.querySelector(".selectButton")) { unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => { element.remove(); }); } else { unsafeWindow.document.querySelectorAll(`.videoTeaser`).forEach((element) => { injectCheckbox(element); }); } }); let deselectAllButton = this.button("deselectAll", (name, event) => { for (const id of selectList.keys()) { selectList.delete(id); } }); let reverseSelectButton = this.button("reverseSelect", (name, event) => { unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => { element.click(); }); }); let selectThisButton = this.button("selectThis", (name, event) => { unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => { let button = element; !button.checked && button.click(); }); }); let deselectThisButton = this.button("deselectThis", (name, event) => { unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => { let button = element; button.checked && button.click(); }); }); let downloadSelectedButton = this.button("downloadSelected", (name, event) => { analyzeDownloadTask(); newToast(ToastType.Info, { text: `%#${name}#%`, close: true }).show(); }); let selectButtons = [injectCheckboxButton, deselectAllButton, reverseSelectButton, selectThisButton, deselectThisButton, downloadSelectedButton]; let downloadThisButton = this.button("downloadThis", async (name, event) => { let ID = unsafeWindow.location.href.toURL().pathname.split("/")[2]; await pushDownloadTask(await parseVideoInfo({ Type: "init", ID }), true); }); let aria2TaskCheckButton = this.button("aria2TaskCheck", (name, event) => { aria2TaskCheckAndRestart(); }); config.experimentalFeatures && originalNodeAppendChild.call(this.interfacePage, aria2TaskCheckButton); switch (this.pageType) { case PageType.Video: originalNodeAppendChild.call(this.interfacePage, downloadThisButton); selectButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; case PageType.Search: case PageType.Profile: case PageType.Home: case PageType.VideoList: case PageType.Subscriptions: case PageType.Playlist: case PageType.Favorites: case PageType.Account: selectButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; case PageType.Page: case PageType.Forum: case PageType.Image: case PageType.ImageList: case PageType.ForumSection: case PageType.ForumThread: default: baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i)); break; } if (config.addUnlistedAndPrivate && this.pageType === PageType.VideoList) { this.parseUnlistedAndPrivate(); } else { GM_getValue("isDebug") && originalConsole.debug("[Debug] Conditions not met: addUnlistedAndPrivate or pageType mismatch."); } } inject() { this.observer.observe(unsafeWindow.document.getElementById("app"), { childList: true, subtree: true }); if (!unsafeWindow.document.querySelector("#pluginMenu")) { originalNodeAppendChild.call(unsafeWindow.document.body, this.interface); this.pageType = getPageType() ?? this.pageType; } } }; var pluginMenu = new menu(); var editConfig = new configEdit(config); var selectList = new VCSyncDictionary("selectList"); var pageStatus = new MultiPage(); var pageSelectButtons = new Dictionary(); var selected = renderNode({ nodeType: "span", childs: ` %#selected#% ${selectList.size} ` }); var watermark = renderNode({ nodeType: "p", className: "fixed-bottom-right", childs: [`%#appName#% ${GM_getValue("version")} `, selected, GM_getValue("isDebug") ? `%#isDebug#%` : ""] }); function getSelectButton(id) { return pageSelectButtons.has(id) ? pageSelectButtons.get(id) : unsafeWindow.document.querySelector(`input.selectButton[videoid="${id}"]`); } function saveSelectList() { GM_getTabs((tabs) => { if (Object.keys(tabs).length > 1) return; selectList.save(); }); } function updateSelected() { selected.textContent = ` ${i18nList[config.language].selected} ${selectList.size} `; } function updateButtonState(videoID) { const selectButton = getSelectButton(videoID); if (selectButton) selectButton.checked = selectList.has(videoID); } originalAddEventListener.call(unsafeWindow.document, "visibilitychange", saveSelectList); pageStatus.onPageLeave = () => { saveSelectList(); }; selectList.onSet = (key) => { updateButtonState(key); saveSelectList(); updateSelected(); }; selectList.onDel = (key) => { updateButtonState(key); saveSelectList(); updateSelected(); }; selectList.onSync = () => { pageSelectButtons.forEach((value, key) => { updateButtonState(key); }); saveSelectList(); updateSelected(); }; function generateMatadataURL(videoInfo) { const metadataContent = generateMetadataContent(videoInfo); const blob = new Blob([metadataContent], { type: "text/plain" }); return URL.createObjectURL(blob); } function getMatadataPath(videoInfo) { const videoPath = getDownloadPath(videoInfo); return `${videoPath.directory}/${videoPath.baseName}.json`; } function generateMetadataContent(videoInfo) { const metadata = Object.assign(videoInfo, { DownloadPath: getDownloadPath(videoInfo).fullPath, MetaDataVersion: GM_info.script.version }); return JSON.stringify(metadata, (key, value) => { if (value instanceof Date) { return value.toISOString(); } return value; }, 2); } function browserDownloadMetadata(videoInfo) { const url = generateMatadataURL(videoInfo); function toastError(error) { newToast(ToastType.Error, { node: toastNode([`${videoInfo.Title}[${videoInfo.ID}] %#videoMetadata#% %#downloadFailed#%`, { nodeType: "br" }, browserDownloadErrorParse(error)], "%#browserDownload#%"), close: true }).show(); } GM_download({ url, saveAs: false, name: getMatadataPath(videoInfo), onerror: (err) => toastError(err), ontimeout: () => toastError(new Error("%#browserDownloadTimeout#%")), onload: () => URL.revokeObjectURL(url) }); } function othersDownloadMetadata(videoInfo) { const url = generateMatadataURL(videoInfo); const metadataFile = analyzeLocalPath(getMatadataPath(videoInfo)).fullName; const downloadHandle = renderNode({ nodeType: "a", attributes: { href: url, download: metadataFile } }); downloadHandle.click(); downloadHandle.remove(); URL.revokeObjectURL(url); } async function addDownloadTask() { let textArea = renderNode({ nodeType: "textarea", attributes: { placeholder: i18nList[config.language].manualDownloadTips, style: "margin-bottom: 10px;", rows: "16", cols: "96" } }); let body = renderNode({ nodeType: "div", attributes: { id: "pluginOverlay" }, childs: [textArea, { nodeType: "button", events: { click: (e) => { if (!isNullOrUndefined(textArea.value) && !textArea.value.isEmpty()) { let list = []; try { const parsed = JSON.parse(textArea.value); if (Array.isArray(parsed)) { list = parsed.map((item) => { if (Array.isArray(item) && isString(item[0]) && !item[0].isEmpty()) { if (!isVideoInfo(item[1])) { item[1].Type = "init"; item[1].ID = item[1].ID ?? item[0]; item[1].UpdateTime = item[1].UpdateTime ?? Date.now(); } } return [...item]; }); } else { throw new Error("解析结果不是符合预期的列表"); } } catch (error) { list = textArea.value.split("|").map((ID) => [ID.trim(), { Type: "init", ID: ID.trim(), UpdateTime: Date.now() }]); } if (list.length > 0) { analyzeDownloadTask(new Dictionary(list)); } } body.remove(); } }, childs: i18nList[config.language].ok }] }); unsafeWindow.document.body.appendChild(body); } async function downloadTaskUnique(taskList) { let stoped = prune((await aria2API("aria2.tellStopped", [0, 4096, ["gid", "status", "files", "errorCode", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => { let ID = aria2TaskExtractVideoID(task2); if (!isNullOrUndefined(ID) && !ID.isEmpty()) { return { id: ID, data: task2 }; } })); let active = prune((await aria2API("aria2.tellActive", [["gid", "status", "files", "downloadSpeed", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => { let ID = aria2TaskExtractVideoID(task2); if (!isNullOrUndefined(ID) && !ID.isEmpty()) { return { id: ID, data: task2 }; } })); let downloadCompleted = stoped.filter((task2) => task2.data.status === "complete").unique("id"); let startedAndCompleted = [...active, ...downloadCompleted].map((i) => i.id); for (let key of taskList.keysArray().intersect(startedAndCompleted)) { taskList.delete(key); } } async function analyzeDownloadTask(taskList = selectList) { let size = taskList.size; let node = renderNode({ nodeType: "p", childs: `${i18nList[config.language].parsingProgress}[${taskList.size}/${size}]` }); let parsingProgressToast = newToast(ToastType.Info, { node, duration: -1 }); function updateParsingProgress() { node.firstChild.textContent = `${i18nList[config.language].parsingProgress}[${taskList.size}/${size}]`; } parsingProgressToast.show(); if (config.experimentalFeatures && config.downloadType === DownloadType.Aria2) { await downloadTaskUnique(taskList); updateParsingProgress(); } for (let [id, info] of taskList) { await pushDownloadTask(await parseVideoInfo(info)); taskList.delete(id); updateParsingProgress(); !config.enableUnsafeMode && await delay(3e3); } parsingProgressToast.hide(); newToast(ToastType.Info, { text: `%#allCompleted#%`, duration: -1, close: true, onClick() { this.hide(); } }).show(); } async function pushDownloadTask(videoInfo, bypass = false) { switch (videoInfo.Type) { case "full": await db.videos.put(videoInfo, videoInfo.ID); if (!bypass) { const authorInfo = await db.follows.get(videoInfo.AuthorID); if (config.autoFollow && (!authorInfo?.following || !videoInfo.Following)) { await unlimitedFetch(`https://api.iwara.tv/user/${videoInfo.AuthorID}/followers`, { method: "POST", headers: await getAuth() }, { retry: true, successStatus: 201, failStatuses: [404], onFail: async (res) => { newToast(ToastType.Warn, { text: `${videoInfo.Alias} %#autoFollowFailed#% ${res.status}`, close: true, onClick() { this.hide(); } }).show(); }, onRetry: async () => { await refreshToken(); } }); } if (config.autoLike && !videoInfo.Liked) { await unlimitedFetch(`https://api.iwara.tv/video/${videoInfo.ID}/like`, { method: "POST", headers: await getAuth() }, { retry: true, successStatus: 201, failStatuses: [404], onFail: async (res) => { newToast(ToastType.Warn, { text: `${videoInfo.Alias} %#autoLikeFailed#% ${res.status}`, close: true, onClick() { this.hide(); } }).show(); }, onRetry: async () => { await refreshToken(); } }); } if (config.checkDownloadLink && checkIsHaveDownloadLink(`${videoInfo.Description} ${videoInfo.Comments}`)) { let toastBody = toastNode([`${videoInfo.Title}[${videoInfo.ID}] %#findedDownloadLink#%`, { nodeType: "br" }, `%#openVideoLink#%`], "%#createTask#%"); newToast(ToastType.Warn, { node: toastBody, close: config.autoCopySaveFileName, onClick() { GM_openInTab(`https://www.iwara.tv/video/${videoInfo.ID}`, { active: false, insert: true, setParent: true }); if (config.autoCopySaveFileName) { GM_setClipboard(getDownloadPath(videoInfo).fullName, "text"); toastBody.appendChild(renderNode({ nodeType: "p", childs: "%#copySucceed#%" })); } else { this.hide(); } } }).show(); return; } } if (config.checkPriority && videoInfo.DownloadQuality !== config.downloadPriority) { newToast(ToastType.Warn, { node: toastNode([`${videoInfo.Title.truncate(64)}[${videoInfo.ID}] %#downloadQualityError#%`, { nodeType: "br" }, `%#tryReparseDownload#%`], "%#createTask#%"), async onClick() { this.hide(); await pushDownloadTask(await parseVideoInfo(videoInfo)); } }).show(); return; } switch (config.downloadType) { case DownloadType.Aria2: aria2Download(videoInfo); break; case DownloadType.IwaraDownloader: iwaraDownloaderDownload(videoInfo); break; case DownloadType.Browser: browserDownload(videoInfo); break; default: othersDownload(videoInfo); break; } if (config.autoDownloadMetadata) { switch (config.downloadType) { case DownloadType.Others: othersDownloadMetadata(videoInfo); break; case DownloadType.Browser: browserDownloadMetadata(videoInfo); break; default: break; } GM_getValue("isDebug") && originalConsole.debug("[Debug] Download task pushed:", videoInfo); } selectList.delete(videoInfo.ID); break; case "partial": const partialCache = await db.videos.get(videoInfo.ID); if (!isNullOrUndefined(partialCache) && partialCache.Type !== "full") await db.videos.put(videoInfo, videoInfo.ID); case "cache": case "init": return await pushDownloadTask(await parseVideoInfo(videoInfo)); case "fail": const cache = await db.videos.get(videoInfo.ID); newToast(ToastType.Error, { close: true, node: toastNode([`${videoInfo.Title ?? videoInfo.RAW?.title ?? cache?.RAW?.title}[${videoInfo.ID}] %#parsingFailed#%`, { nodeType: "br" }, videoInfo.Msg, { nodeType: "br" }, videoInfo.External ? `%#openVideoLink#%` : `%#tryReparseDownload#%`], "%#createTask#%"), async onClick() { this.hide(); if (videoInfo.External && !isNullOrUndefined(videoInfo.ExternalUrl) && !videoInfo.ExternalUrl.isEmpty()) { GM_openInTab(videoInfo.ExternalUrl, { active: false, insert: true, setParent: true }); } else { await pushDownloadTask(await parseVideoInfo({ Type: "init", ID: videoInfo.ID, RAW: videoInfo.RAW ?? cache?.RAW })); } } }).show(); break; default: GM_getValue("isDebug") && originalConsole.debug("[Debug] Unknown type:", videoInfo); break; } } function uninjectCheckbox(element) { if (element instanceof HTMLElement) { if (element instanceof HTMLInputElement && element.classList.contains("selectButton")) { element.hasAttribute("videoID") && pageSelectButtons.delete(element.getAttribute("videoID")); } if (element.querySelector("input.selectButton")) { element.querySelectorAll(".selectButton").forEach((i) => i.hasAttribute("videoID") && pageSelectButtons.delete(i.getAttribute("videoID"))); } } } async function injectCheckbox(element) { let ID = element.querySelector("a.videoTeaser__thumbnail").href.toURL().pathname.split("/")[2]; if (isNullOrUndefined(ID)) return; let info = await db.videos.get(ID); let Title = info?.Type === "full" || info?.Type === "partial" ? info?.Title : info?.RAW?.title ?? element.querySelector(".videoTeaser__title")?.getAttribute("title") ?? void 0; let Alias = info?.Type === "full" || info?.Type === "partial" ? info?.Alias : info?.RAW?.user.name ?? element.querySelector("a.username")?.getAttribute("title") ?? void 0; let Author = info?.Type === "full" || info?.Type === "partial" ? info?.Author : info?.RAW?.user.username ?? element.querySelector("a.username")?.href.toURL().pathname.split("/").pop(); let UploadTime = info?.Type === "full" || info?.Type === "partial" ? info?.UploadTime : new Date(info?.RAW?.updatedAt ?? 0).getTime(); let button = renderNode({ nodeType: "input", attributes: { type: "checkbox", videoID: ID, checked: selectList.has(ID) ? true : void 0, videoName: Title, videoAlias: Alias, videoAuthor: Author, videoUploadTime: UploadTime }, className: "selectButton", events: { click: (event) => { event.target.checked ? selectList.set(ID, { Type: "init", ID, Title, Alias, Author, UploadTime }) : selectList.delete(ID); event.stopPropagation(); event.stopImmediatePropagation(); return false; } } }); let item = element.querySelector(".videoTeaser__thumbnail")?.parentElement; item?.style.setProperty("position", "relative"); pageSelectButtons.set(ID, button); originalNodeAppendChild.call(item, button); if (!isNullOrUndefined(Author)) { const AuthorInfo = await db.follows.where("username").equals(Author).first(); if (AuthorInfo?.following && element.querySelector(".videoTeaser__thumbnail")?.querySelector(".follow") === null) { originalNodeAppendChild.call(element.querySelector(".videoTeaser__thumbnail"), renderNode({ nodeType: "div", className: "follow", childs: { nodeType: "div", className: ["text", "text--white", "text--tiny", "text--bold"], childs: "%#following#%" } })); } } if (pluginMenu.pageType === PageType.Playlist) { let deletePlaylistItme = renderNode({ nodeType: "button", attributes: { videoID: ID }, childs: "%#delete#%", className: "deleteButton", events: { click: async (event) => { if ((await unlimitedFetch(`https://api.iwara.tv/playlist/${unsafeWindow.location.pathname.split("/")[2]}/${ID}`, { method: "DELETE", headers: await getAuth() })).ok) { newToast(ToastType.Info, { text: `${Title} %#deleteSucceed#%`, close: true }).show(); deletePlaylistItme.remove(); } event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); return false; } } }); originalNodeAppendChild.call(item, deletePlaylistItme); } } function getPageType(mutationsList) { if (unsafeWindow.location.pathname.toLowerCase().endsWith("/search")) { return PageType.Search; } const extractPageType = (page) => { if (isNullOrUndefined(page)) return void 0; if (page.classList.length < 2) return PageType.Page; const pageClass = page.classList[1]?.split("-").pop(); return !isNullOrUndefined(pageClass) && isPageType(pageClass) ? pageClass : PageType.Page; }; if (isNullOrUndefined(mutationsList)) { return extractPageType(unsafeWindow.document.querySelector(".page")); } for (const mutation of mutationsList) { if (mutation.type === "childList" && mutation.addedNodes.length > 0) { return extractPageType(Array.from(mutation.addedNodes).find((node) => node instanceof Element && node.classList.contains("page"))); } } } function pageChange() { pluginMenu.pageType = getPageType() ?? pluginMenu.pageType; GM_getValue("isDebug") && originalConsole.debug("[Debug]", pageSelectButtons); } function hijackAddEventListener() { unsafeWindow.EventTarget.prototype.addEventListener = function(type2, listener, options) { originalAddEventListener.call(this, type2, listener, options); }; } function hijackNodeAppendChild() { Node.prototype.appendChild = function(node) { if (node instanceof HTMLElement && node.classList.contains("videoTeaser")) { injectCheckbox(node); } return originalNodeAppendChild.call(this, node); }; } function hijackNodeRemoveChild() { Node.prototype.removeChild = function(child) { uninjectCheckbox(child); return originalNodeRemoveChild.apply(this, [child]); }; } function hijackElementRemove() { Element.prototype.remove = function() { uninjectCheckbox(this); return originalElementRemove.apply(this); }; } function hijackHistoryPushState() { unsafeWindow.history.pushState = function(...args) { originalHistoryPushState.apply(this, args); pageChange(); }; } function hijackHistoryReplaceState() { unsafeWindow.history.replaceState = function(...args) { originalHistoryReplaceState.apply(this, args); pageChange(); }; } function hijackStorage() { unsafeWindow.Storage.prototype.setItem = function(key, value) { originalStorageSetItem.call(this, key, value); if (key === "token") pluginMenu.pageChange(); }; unsafeWindow.Storage.prototype.removeItem = function(key) { originalStorageRemoveItem.call(this, key); if (key === "token") pluginMenu.pageChange(); }; unsafeWindow.Storage.prototype.clear = function() { originalStorageClear.call(this); pluginMenu.pageChange(); }; } function firstRun() { originalConsole.log("First run config reset!"); GM_listValues().forEach((i) => GM_deleteValue(i)); Config.destroyInstance(); editConfig = new configEdit(config); let confirmButton = renderNode({ nodeType: "button", attributes: { disabled: true, title: i18nList[config.language].ok }, childs: "%#ok#%", events: { click: () => { GM_setValue("isFirstRun", false); GM_setValue("version", GM_info.script.version); unsafeWindow.document.querySelector("#pluginOverlay")?.remove(); editConfig.inject(); } } }); originalNodeAppendChild.call(unsafeWindow.document.body, renderNode({ nodeType: "div", attributes: { id: "pluginOverlay" }, childs: [{ nodeType: "div", className: "main", childs: [{ nodeType: "p", childs: i18nList[config.language].useHelpForBase }, { nodeType: "p", childs: "%#useHelpForInjectCheckbox#%" }, { nodeType: "p", childs: "%#useHelpForCheckDownloadLink#%" }, { nodeType: "p", childs: i18nList[config.language].useHelpForManualDownload }, { nodeType: "p", childs: i18nList[config.language].useHelpForBugreport }] }, { nodeType: "div", className: "checkbox-container", childs: { nodeType: "label", className: ["checkbox-label", "rainbow-text"], childs: [{ nodeType: "input", className: "checkbox", attributes: { type: "checkbox", name: "agree-checkbox" }, events: { change: (event) => { confirmButton.disabled = !event.target.checked; } } }, "%#alreadyKnowHowToUse#%"] } }, confirmButton] })); } async function main() { if (new Version(GM_getValue("version", "0.0.0")).compare(new Version("3.3.0")) === VersionState.Low) { GM_setValue("isFirstRun", true); alert(i18nList[config.language].configurationIncompatible); } if (GM_getValue("isFirstRun", true)) { firstRun(); return; } if (new Version(GM_getValue("version", "0.0.0")).compare(new Version("3.3.22")) === VersionState.Low) { alert(i18nList[config.language].configurationIncompatible); try { pageStatus.suicide(); selectList.clear(); GM_deleteValue("selectList"); await db.delete(); GM_setValue("version", GM_info.script.version); unsafeWindow.location.reload(); } catch (error) { originalConsole.error(error); } return; } if (!await check()) { newToast(ToastType.Info, { text: `%#configError#%`, duration: 60 * 1e3 }).show(); editConfig.inject(); return; } GM_setValue("version", GM_info.script.version); hijackAddEventListener(); if (config.autoInjectCheckbox) hijackNodeAppendChild(); hijackNodeRemoveChild(); hijackElementRemove(); hijackStorage(); hijackHistoryPushState(); hijackHistoryReplaceState(); originalAddEventListener("mouseover", (event) => { mouseTarget = event.target instanceof Element ? event.target : null; }); originalAddEventListener("keydown", (event) => { const keyboardEvent = event; if (keyboardEvent.code === "Space" && !isNullOrUndefined(mouseTarget)) { let element = findElement(mouseTarget, ".videoTeaser"); let button = element && (element.matches(".selectButton") ? element : element.querySelector(".selectButton")); button && button.click(); button && keyboardEvent.preventDefault(); } }); new MutationObserver(async (m, o) => { if (m.some((m2) => m2.type === "childList" && unsafeWindow.document.getElementById("app"))) { pluginMenu.inject(); o.disconnect(); } }).observe(unsafeWindow.document.body, { childList: true, subtree: true }); originalNodeAppendChild.call(unsafeWindow.document.body, watermark); if (isLoggedIn()) { let user = await (await unlimitedFetch("https://api.iwara.tv/user", { method: "GET", headers: await getAuth() })).json(); let authorProfile = await db.follows.where("username").equals("dawn").first(); if (isNullOrUndefined(authorProfile)) { authorProfile = (await (await unlimitedFetch("https://api.iwara.tv/profile/dawn", { method: "GET", headers: await getAuth() })).json()).user; if (user.user.id !== authorProfile.id) { if (!authorProfile.following) { unlimitedFetch(`https://api.iwara.tv/user/${authorProfile.id}/followers`, { method: "POST", headers: await getAuth() }); } if (!authorProfile.friend) { unlimitedFetch(`https://api.iwara.tv/user/${authorProfile.id}/friends`, { method: "POST", headers: await getAuth() }); } } } } newToast(ToastType.Info, { node: toastNode(i18nList[config.language].notice), duration: 1e4, gravity: "bottom", position: "center", onClick() { this.hide(); } }).show(); } if (!unsafeWindow.IwaraDownloadTool) { unsafeWindow.IwaraDownloadTool = true; if (GM_getValue("isDebug")) { debugger; unsafeWindow.pageStatus = pageStatus; originalConsole.debug(stringify(GM_info)); } unsafeWindow.fetch = async (input, init) => { GM_getValue("isDebug") && originalConsole.debug(`[Debug] Fetch ${input}`); let url = (input instanceof Request ? input.url : input instanceof URL ? input.href : input).toURL(); if (!isNullOrUndefined(init) && !isNullOrUndefined(init.headers)) { let authorization = null; if (init.headers instanceof Headers) { authorization = init.headers.has("Authorization") ? init.headers.get("Authorization") : null; } else { if (Array.isArray(init.headers)) { let index = init.headers.findIndex(([key, value]) => key.toLowerCase() !== "authorization"); if (!(index < 0)) authorization = init.headers[index][1]; } else { for (const key in init.headers) { if (key.toLowerCase() !== "authorization") continue; authorization = init.headers[key]; break; } } } if (!isNullOrUndefined(authorization)) { let playload = getPlayload(authorization); let token = authorization.split(" ").pop() ?? ""; if (playload["type"] === "refresh_token" && !token.isEmpty()) { localStorage.setItem("token", token); config.authorization = token; GM_getValue("isDebug") && originalConsole.debug(`[Debug] refresh_token: 凭证已隐藏`); } } } return new Promise((resolve, reject) => originalFetch(input, init).then(async (response) => { if (url.hostname !== "api.iwara.tv" || url.pathname.isEmpty()) return resolve(response); let path = url.pathname.toLowerCase().split("/").slice(1); switch (path[0]) { case "user": if (path[1] === "token") { const cloneResponse2 = response.clone(); if (!cloneResponse2.ok) break; const { accessToken } = await cloneResponse2.json(); let token = localStorage.getItem("accessToken"); if (isNullOrUndefined(token) || token !== accessToken) localStorage.setItem("accessToken", accessToken); } break; case "videos": const cloneResponse = response.clone(); if (!cloneResponse.ok) break; const cloneBody = await cloneResponse.json(); const list = (await Promise.allSettled(cloneBody.results.map((info) => parseVideoInfo({ Type: "cache", ID: info.id, RAW: info })))).filter((i) => i.status === "fulfilled").map((i) => i.value).filter((i) => i.Type === "partial" || i.Type === "full"); const toUpdate = list.difference((await db.videos.where("ID").anyOf(list.map((v) => v.ID)).toArray()).filter((v) => v.Type === "full"), "ID"); if (toUpdate.any()) { await db.videos.bulkPut(toUpdate); } if (!config.addUnlistedAndPrivate) break; GM_getValue("isDebug") && originalConsole.debug("[Debug]", url.searchParams); if (url.searchParams.has("user")) break; if (url.searchParams.has("subscribed")) break; if (url.searchParams.has("sort") ? url.searchParams.get("sort") !== "date" : false) break; const sortedList = list.sort((a, b) => a.UploadTime - b.UploadTime); const minTime = sortedList.at(0).UploadTime; const maxTime = sortedList.at(-1).UploadTime; const startTime = new Date(minTime).sub({ hours: 4 }).getTime(); const endTime = new Date(maxTime).add({ hours: 4 }).getTime(); const cache = (await db.getFilteredVideos(startTime, endTime)).filter((i) => i.Type === "partial" || i.Type === "full").sort((a, b) => a.UploadTime - b.UploadTime).map((i) => i.RAW); if (!cache.any()) break; cloneBody.count += cache.length; cloneBody.limit += cache.length; cloneBody.results.push(...cache); return resolve(new Response(JSON.stringify(cloneBody), { status: cloneResponse.status, statusText: cloneResponse.statusText, headers: Object.fromEntries(cloneResponse.headers.entries()) })); default: break; } return resolve(response); }).catch((err) => reject(err))); }; GM_getTabs((tabs) => { if (Object.keys(tabs).length != 1) return; try { selectList = VCSyncDictionary.load("selectList") ?? new VCSyncDictionary("selectList"); } catch (error) { GM_deleteValue("selectList"); selectList = new VCSyncDictionary("selectList"); } }); GM_addStyle(main_default); (unsafeWindow.document.body ? Promise.resolve() : new Promise((resolve) => originalAddEventListener.call(unsafeWindow.document, "DOMContentLoaded", resolve))).then(main); } })();