Resalta las pistas escuchadas en sitios de música. Cuanto más escuchas — más brillante.
// ==UserScript==
// @name Music Tracker
// @name:ru Music Tracker — Музыкальный трекер
// @name:fr Music Tracker — Traqueur musical
// @name:de Music Tracker — Musik-Tracker
// @name:pl Music Tracker — Tracker muzyczny
// @name:ko Music Tracker — 음악 트래커
// @name:es Music Tracker — Rastreador musical
// @version 0.2.0
// @author Ilya K
// @description Track listened music on supported platforms with play count highlighting
// @description:ru Подсвечивает прослушанные треки на музыкальных сайтах. Чем больше слушаете — тем ярче подсветка.
// @description:fr Met en évidence les pistes écoutées sur les sites de musique. Plus vous écoutez — plus c'est vif.
// @description:de Hebt gehörte Titel auf Musikseiten hervor. Je mehr Sie hören — desto heller.
// @description:pl Podświetla słuchane utwory na stronach muzycznych. Im więcej słuchasz — tym jaśniej.
// @description:ko 음악 사이트에서 들은 트랙을 강조 표시합니다. 많이 들을수록 더 밝아집니다.
// @description:es Resalta las pistas escuchadas en sitios de música. Cuanto más escuchas — más brillante.
// @license ISC
// @match https://vk.com/*
// @match https://vk.ru/*
// @match https://music.yandex.ru/*
// @match https://music.yandex.com/*
// @match https://music.youtube.com/*
// @match https://open.spotify.com/*
// @match https://soundcloud.com/*
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @run-at document-idle
// @namespace https://github.com/music-tracker
// ==/UserScript==
(function () {
'use strict';
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var dexie_min$1 = { exports: {} };
var dexie_min = dexie_min$1.exports;
var hasRequiredDexie_min;
function requireDexie_min() {
if (hasRequiredDexie_min) return dexie_min$1.exports;
hasRequiredDexie_min = 1;
(function(module, exports$1) {
((e, t2) => {
module.exports = t2();
})(dexie_min, function() {
var B = function(e2, t3) {
return (B = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? function(e3, t4) {
e3.__proto__ = t4;
} : function(e3, t4) {
for (var n2 in t4) Object.prototype.hasOwnProperty.call(t4, n2) && (e3[n2] = t4[n2]);
}))(e2, t3);
};
var _ = function() {
return (_ = Object.assign || function(e2) {
for (var t3, n2 = 1, r2 = arguments.length; n2 < r2; n2++) for (var o2 in t3 = arguments[n2]) Object.prototype.hasOwnProperty.call(t3, o2) && (e2[o2] = t3[o2]);
return e2;
}).apply(this, arguments);
};
function R(e2, t3, n2) {
for (var r2, o2 = 0, i2 = t3.length; o2 < i2; o2++) !r2 && o2 in t3 || ((r2 = r2 || Array.prototype.slice.call(t3, 0, o2))[o2] = t3[o2]);
return e2.concat(r2 || Array.prototype.slice.call(t3));
}
var f = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : "undefined" != typeof window ? window : commonjsGlobal, O = Object.keys, x = Array.isArray;
function a(t3, n2) {
return "object" == typeof n2 && O(n2).forEach(function(e2) {
t3[e2] = n2[e2];
}), t3;
}
"undefined" == typeof Promise || f.Promise || (f.Promise = Promise);
var F = Object.getPrototypeOf, N = {}.hasOwnProperty;
function m(e2, t3) {
return N.call(e2, t3);
}
function M(t3, n2) {
"function" == typeof n2 && (n2 = n2(F(t3))), ("undefined" == typeof Reflect ? O : Reflect.ownKeys)(n2).forEach(function(e2) {
u(t3, e2, n2[e2]);
});
}
var L = Object.defineProperty;
function u(e2, t3, n2, r2) {
L(e2, t3, a(n2 && m(n2, "get") && "function" == typeof n2.get ? { get: n2.get, set: n2.set, configurable: true } : { value: n2, configurable: true, writable: true }, r2));
}
function U(t3) {
return { from: function(e2) {
return t3.prototype = Object.create(e2.prototype), u(t3.prototype, "constructor", t3), { extend: M.bind(null, t3.prototype) };
} };
}
var z = Object.getOwnPropertyDescriptor;
var V = [].slice;
function W(e2, t3, n2) {
return V.call(e2, t3, n2);
}
function Y(e2, t3) {
return t3(e2);
}
function $(e2) {
if (!e2) throw new Error("Assertion Failed");
}
function Q(e2) {
f.setImmediate ? setImmediate(e2) : setTimeout(e2, 0);
}
function c(e2, t3) {
if ("string" == typeof t3 && m(e2, t3)) return e2[t3];
if (!t3) return e2;
if ("string" != typeof t3) {
for (var n2 = [], r2 = 0, o2 = t3.length; r2 < o2; ++r2) {
var i2 = c(e2, t3[r2]);
n2.push(i2);
}
return n2;
}
var a2, u2 = t3.indexOf(".");
return -1 === u2 || null == (a2 = e2[t3.substr(0, u2)]) ? void 0 : c(a2, t3.substr(u2 + 1));
}
function b(e2, t3, n2) {
if (e2 && void 0 !== t3 && !("isFrozen" in Object && Object.isFrozen(e2))) if ("string" != typeof t3 && "length" in t3) {
$("string" != typeof n2 && "length" in n2);
for (var r2 = 0, o2 = t3.length; r2 < o2; ++r2) b(e2, t3[r2], n2[r2]);
} else {
var i2, a2, u2 = t3.indexOf(".");
-1 !== u2 ? (i2 = t3.substr(0, u2), "" === (u2 = t3.substr(u2 + 1)) ? void 0 === n2 ? x(e2) && !isNaN(parseInt(i2)) ? e2.splice(i2, 1) : delete e2[i2] : e2[i2] = n2 : b(a2 = (a2 = e2[i2]) && m(e2, i2) ? a2 : e2[i2] = {}, u2, n2)) : void 0 === n2 ? x(e2) && !isNaN(parseInt(t3)) ? e2.splice(t3, 1) : delete e2[t3] : e2[t3] = n2;
}
}
function G(e2) {
var t3, n2 = {};
for (t3 in e2) m(e2, t3) && (n2[t3] = e2[t3]);
return n2;
}
var X = [].concat;
function H(e2) {
return X.apply([], e2);
}
var e = "BigUint64Array,BigInt64Array,Array,Boolean,String,Date,RegExp,Blob,File,FileList,FileSystemFileHandle,FileSystemDirectoryHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey".split(",").concat(H([8, 16, 32, 64].map(function(t3) {
return ["Int", "Uint", "Float"].map(function(e2) {
return e2 + t3 + "Array";
});
}))).filter(function(e2) {
return f[e2];
}), J = new Set(e.map(function(e2) {
return f[e2];
}));
var Z = null;
function ee(e2) {
Z = new WeakMap();
e2 = (function e3(t3) {
if (!t3 || "object" != typeof t3) return t3;
var n2 = Z.get(t3);
if (n2) return n2;
if (x(t3)) {
n2 = [], Z.set(t3, n2);
for (var r2 = 0, o2 = t3.length; r2 < o2; ++r2) n2.push(e3(t3[r2]));
} else if (J.has(t3.constructor)) n2 = t3;
else {
var i2, a2 = F(t3);
for (i2 in n2 = a2 === Object.prototype ? {} : Object.create(a2), Z.set(t3, n2), t3) m(t3, i2) && (n2[i2] = e3(t3[i2]));
}
return n2;
})(e2);
return Z = null, e2;
}
var te = {}.toString;
function ne(e2) {
return te.call(e2).slice(8, -1);
}
var re = "undefined" != typeof Symbol ? Symbol.iterator : "@@iterator", oe = "symbol" == typeof re ? function(e2) {
var t3;
return null != e2 && (t3 = e2[re]) && t3.apply(e2);
} : function() {
return null;
};
function ie(e2, t3) {
t3 = e2.indexOf(t3);
0 <= t3 && e2.splice(t3, 1);
}
var ae = {};
function n(e2) {
var t3, n2, r2, o2;
if (1 === arguments.length) {
if (x(e2)) return e2.slice();
if (this === ae && "string" == typeof e2) return [e2];
if (o2 = oe(e2)) for (n2 = []; !(r2 = o2.next()).done; ) n2.push(r2.value);
else {
if (null == e2) return [e2];
if ("number" != typeof (t3 = e2.length)) return [e2];
for (n2 = new Array(t3); t3--; ) n2[t3] = e2[t3];
}
} else for (t3 = arguments.length, n2 = new Array(t3); t3--; ) n2[t3] = arguments[t3];
return n2;
}
var ue = "undefined" != typeof Symbol ? function(e2) {
return "AsyncFunction" === e2[Symbol.toStringTag];
} : function() {
return false;
}, e = ["Unknown", "Constraint", "Data", "TransactionInactive", "ReadOnly", "Version", "NotFound", "InvalidState", "InvalidAccess", "Abort", "Timeout", "QuotaExceeded", "Syntax", "DataClone"], t2 = ["Modify", "Bulk", "OpenFailed", "VersionChange", "Schema", "Upgrade", "InvalidTable", "MissingAPI", "NoSuchDatabase", "InvalidArgument", "SubTransaction", "Unsupported", "Internal", "DatabaseClosed", "PrematureCommit", "ForeignAwait"].concat(e), se = { 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 ce(e2, t3) {
this.name = e2, this.message = t3;
}
function le(e2, t3) {
return e2 + ". Errors: " + Object.keys(t3).map(function(e3) {
return t3[e3].toString();
}).filter(function(e3, t4, n2) {
return n2.indexOf(e3) === t4;
}).join("\n");
}
function fe(e2, t3, n2, r2) {
this.failures = t3, this.failedKeys = r2, this.successCount = n2, this.message = le(e2, t3);
}
function he(e2, t3) {
this.name = "BulkError", this.failures = Object.keys(t3).map(function(e3) {
return t3[e3];
}), this.failuresByPos = t3, this.message = le(e2, this.failures);
}
U(ce).from(Error).extend({ toString: function() {
return this.name + ": " + this.message;
} }), U(fe).from(ce), U(he).from(ce);
var de = t2.reduce(function(e2, t3) {
return e2[t3] = t3 + "Error", e2;
}, {}), pe = ce, k = t2.reduce(function(e2, n2) {
var r2 = n2 + "Error";
function t3(e3, t4) {
this.name = r2, e3 ? "string" == typeof e3 ? (this.message = "".concat(e3).concat(t4 ? "\n " + t4 : ""), this.inner = t4 || null) : "object" == typeof e3 && (this.message = "".concat(e3.name, " ").concat(e3.message), this.inner = e3) : (this.message = se[n2] || r2, this.inner = null);
}
return U(t3).from(pe), e2[n2] = t3, e2;
}, {}), ye = (k.Syntax = SyntaxError, k.Type = TypeError, k.Range = RangeError, e.reduce(function(e2, t3) {
return e2[t3 + "Error"] = k[t3], e2;
}, {}));
e = t2.reduce(function(e2, t3) {
return -1 === ["Syntax", "Type", "Range"].indexOf(t3) && (e2[t3 + "Error"] = k[t3]), e2;
}, {});
function g() {
}
function ve(e2) {
return e2;
}
function me(t3, n2) {
return null == t3 || t3 === ve ? n2 : function(e2) {
return n2(t3(e2));
};
}
function be(e2, t3) {
return function() {
e2.apply(this, arguments), t3.apply(this, arguments);
};
}
function ge(o2, i2) {
return o2 === g ? i2 : function() {
var e2 = o2.apply(this, arguments), t3 = (void 0 !== e2 && (arguments[0] = e2), this.onsuccess), n2 = this.onerror, r2 = (this.onsuccess = null, this.onerror = null, i2.apply(this, arguments));
return t3 && (this.onsuccess = this.onsuccess ? be(t3, this.onsuccess) : t3), n2 && (this.onerror = this.onerror ? be(n2, this.onerror) : n2), void 0 !== r2 ? r2 : e2;
};
}
function we(n2, r2) {
return n2 === g ? r2 : function() {
n2.apply(this, arguments);
var e2 = this.onsuccess, t3 = this.onerror;
this.onsuccess = this.onerror = null, r2.apply(this, arguments), e2 && (this.onsuccess = this.onsuccess ? be(e2, this.onsuccess) : e2), t3 && (this.onerror = this.onerror ? be(t3, this.onerror) : t3);
};
}
function _e(o2, i2) {
return o2 === g ? i2 : function(e2) {
var t3 = o2.apply(this, arguments), e2 = (a(e2, t3), this.onsuccess), n2 = this.onerror, r2 = (this.onsuccess = null, this.onerror = null, i2.apply(this, arguments));
return e2 && (this.onsuccess = this.onsuccess ? be(e2, this.onsuccess) : e2), n2 && (this.onerror = this.onerror ? be(n2, this.onerror) : n2), void 0 === t3 ? void 0 === r2 ? void 0 : r2 : a(t3, r2);
};
}
function xe(e2, t3) {
return e2 === g ? t3 : function() {
return false !== t3.apply(this, arguments) && e2.apply(this, arguments);
};
}
function ke(o2, i2) {
return o2 === g ? i2 : function() {
var e2 = o2.apply(this, arguments);
if (e2 && "function" == typeof e2.then) {
for (var t3 = this, n2 = arguments.length, r2 = new Array(n2); n2--; ) r2[n2] = arguments[n2];
return e2.then(function() {
return i2.apply(t3, r2);
});
}
return i2.apply(this, arguments);
};
}
e.ModifyError = fe, e.DexieError = ce, e.BulkError = he;
var l = "undefined" != typeof location && /^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href);
function Oe(e2) {
l = e2;
}
var Pe = {}, Ke = 100, Ee = "undefined" == typeof Promise ? [] : (t2 = Promise.resolve(), "undefined" != typeof crypto && crypto.subtle ? [Ee = crypto.subtle.digest("SHA-512", new Uint8Array([0])), F(Ee), t2] : [t2, F(t2), t2]), t2 = Ee[0], Se = Ee[1], Se = Se && Se.then, Ae = t2 && t2.constructor, Ce = !!Ee[2];
var je = function(e2, t3) {
Re.push([e2, t3]), Ie && (queueMicrotask(Ye), Ie = false);
}, Te = true, Ie = true, qe = [], De = [], Be = ve, s = { id: "global", global: true, ref: 0, unhandleds: [], onunhandled: g, pgp: false, env: {}, finalize: g }, P = s, Re = [], Fe = 0, Ne = [];
function K(e2) {
if ("object" != typeof this) throw new TypeError("Promises must be constructed via new");
this._listeners = [], this._lib = false;
var t3 = this._PSD = P;
if ("function" != typeof e2) {
if (e2 !== Pe) throw new TypeError("Not a function");
this._state = arguments[1], this._value = arguments[2], false === this._state && Ue(this, this._value);
} else this._state = null, this._value = null, ++t3.ref, (function t4(r2, e3) {
try {
e3(function(n2) {
if (null === r2._state) {
if (n2 === r2) throw new TypeError("A promise cannot be resolved with itself.");
var e4 = r2._lib && $e();
n2 && "function" == typeof n2.then ? t4(r2, function(e5, t5) {
n2 instanceof K ? n2._then(e5, t5) : n2.then(e5, t5);
}) : (r2._state = true, r2._value = n2, ze(r2)), e4 && Qe();
}
}, Ue.bind(null, r2));
} catch (e4) {
Ue(r2, e4);
}
})(this, e2);
}
var Me = { get: function() {
var u2 = P, t3 = et;
function e2(n2, r2) {
var o2 = this, i2 = !u2.global && (u2 !== P || t3 !== et), a2 = i2 && !w(), e3 = new K(function(e4, t4) {
Ve(o2, new Le(ut(n2, u2, i2, a2), ut(r2, u2, i2, a2), e4, t4, u2));
});
return this._consoleTask && (e3._consoleTask = this._consoleTask), e3;
}
return e2.prototype = Pe, e2;
}, set: function(e2) {
u(this, "then", e2 && e2.prototype === Pe ? Me : { get: function() {
return e2;
}, set: Me.set });
} };
function Le(e2, t3, n2, r2, o2) {
this.onFulfilled = "function" == typeof e2 ? e2 : null, this.onRejected = "function" == typeof t3 ? t3 : null, this.resolve = n2, this.reject = r2, this.psd = o2;
}
function Ue(e2, t3) {
var n2, r2;
De.push(t3), null === e2._state && (n2 = e2._lib && $e(), t3 = Be(t3), e2._state = false, e2._value = t3, r2 = e2, qe.some(function(e3) {
return e3._value === r2._value;
}) || qe.push(r2), ze(e2), n2) && Qe();
}
function ze(e2) {
var t3 = e2._listeners;
e2._listeners = [];
for (var n2 = 0, r2 = t3.length; n2 < r2; ++n2) Ve(e2, t3[n2]);
var o2 = e2._PSD;
--o2.ref || o2.finalize(), 0 === Fe && (++Fe, je(function() {
0 == --Fe && Ge();
}, []));
}
function Ve(e2, t3) {
if (null === e2._state) e2._listeners.push(t3);
else {
var n2 = e2._state ? t3.onFulfilled : t3.onRejected;
if (null === n2) return (e2._state ? t3.resolve : t3.reject)(e2._value);
++t3.psd.ref, ++Fe, je(We, [n2, e2, t3]);
}
}
function We(e2, t3, n2) {
try {
var r2, o2 = t3._value;
!t3._state && De.length && (De = []), r2 = l && t3._consoleTask ? t3._consoleTask.run(function() {
return e2(o2);
}) : e2(o2), t3._state || -1 !== De.indexOf(o2) || ((e3) => {
for (var t4 = qe.length; t4; ) if (qe[--t4]._value === e3._value) return qe.splice(t4, 1);
})(t3), n2.resolve(r2);
} catch (e3) {
n2.reject(e3);
} finally {
0 == --Fe && Ge(), --n2.psd.ref || n2.psd.finalize();
}
}
function Ye() {
at(s, function() {
$e() && Qe();
});
}
function $e() {
var e2 = Te;
return Ie = Te = false, e2;
}
function Qe() {
var e2, t3, n2;
do {
for (; 0 < Re.length; ) for (e2 = Re, Re = [], n2 = e2.length, t3 = 0; t3 < n2; ++t3) {
var r2 = e2[t3];
r2[0].apply(null, r2[1]);
}
} while (0 < Re.length);
Ie = Te = true;
}
function Ge() {
for (var e2 = qe, t3 = (qe = [], e2.forEach(function(e3) {
e3._PSD.onunhandled.call(null, e3._value, e3);
}), Ne.slice(0)), n2 = t3.length; n2; ) t3[--n2]();
}
function Xe(e2) {
return new K(Pe, false, e2);
}
function E(n2, r2) {
var o2 = P;
return function() {
var e2 = $e(), t3 = P;
try {
return h(o2, true), n2.apply(this, arguments);
} catch (e3) {
r2 && r2(e3);
} finally {
h(t3, false), e2 && Qe();
}
};
}
M(K.prototype, { then: Me, _then: function(e2, t3) {
Ve(this, new Le(null, null, e2, t3, P));
}, catch: function(e2) {
var t3, n2;
return 1 === arguments.length ? this.then(null, e2) : (t3 = e2, n2 = arguments[1], "function" == typeof t3 ? this.then(null, function(e3) {
return (e3 instanceof t3 ? n2 : Xe)(e3);
}) : this.then(null, function(e3) {
return (e3 && e3.name === t3 ? n2 : Xe)(e3);
}));
}, finally: function(t3) {
return this.then(function(e2) {
return K.resolve(t3()).then(function() {
return e2;
});
}, function(e2) {
return K.resolve(t3()).then(function() {
return Xe(e2);
});
});
}, timeout: function(r2, o2) {
var i2 = this;
return r2 < 1 / 0 ? new K(function(e2, t3) {
var n2 = setTimeout(function() {
return t3(new k.Timeout(o2));
}, r2);
i2.then(e2, t3).finally(clearTimeout.bind(null, n2));
}) : this;
} }), "undefined" != typeof Symbol && Symbol.toStringTag && u(K.prototype, Symbol.toStringTag, "Dexie.Promise"), s.env = it(), M(K, { all: function() {
var i2 = n.apply(null, arguments).map(rt);
return new K(function(n2, r2) {
0 === i2.length && n2([]);
var o2 = i2.length;
i2.forEach(function(e2, t3) {
return K.resolve(e2).then(function(e3) {
i2[t3] = e3, --o2 || n2(i2);
}, r2);
});
});
}, resolve: function(n2) {
return n2 instanceof K ? n2 : n2 && "function" == typeof n2.then ? new K(function(e2, t3) {
n2.then(e2, t3);
}) : new K(Pe, true, n2);
}, reject: Xe, race: function() {
var e2 = n.apply(null, arguments).map(rt);
return new K(function(t3, n2) {
e2.map(function(e3) {
return K.resolve(e3).then(t3, n2);
});
});
}, PSD: { get: function() {
return P;
}, set: function(e2) {
return P = e2;
} }, totalEchoes: { get: function() {
return et;
} }, newPSD: v, usePSD: at, scheduler: { get: function() {
return je;
}, set: function(e2) {
je = e2;
} }, rejectionMapper: { get: function() {
return Be;
}, set: function(e2) {
Be = e2;
} }, follow: function(o2, n2) {
return new K(function(e2, t3) {
return v(function(n3, r2) {
var e3 = P;
e3.unhandleds = [], e3.onunhandled = r2, e3.finalize = be(function() {
var t4, e4 = this;
t4 = function() {
0 === e4.unhandleds.length ? n3() : r2(e4.unhandleds[0]);
}, Ne.push(function e5() {
t4(), Ne.splice(Ne.indexOf(e5), 1);
}), ++Fe, je(function() {
0 == --Fe && Ge();
}, []);
}, e3.finalize), o2();
}, n2, e2, t3);
});
} }), Ae && (Ae.allSettled && u(K, "allSettled", function() {
var e2 = n.apply(null, arguments).map(rt);
return new K(function(n2) {
0 === e2.length && n2([]);
var r2 = e2.length, o2 = new Array(r2);
e2.forEach(function(e3, t3) {
return K.resolve(e3).then(function(e4) {
return o2[t3] = { status: "fulfilled", value: e4 };
}, function(e4) {
return o2[t3] = { status: "rejected", reason: e4 };
}).then(function() {
return --r2 || n2(o2);
});
});
});
}), Ae.any && "undefined" != typeof AggregateError && u(K, "any", function() {
var e2 = n.apply(null, arguments).map(rt);
return new K(function(n2, r2) {
0 === e2.length && r2(new AggregateError([]));
var o2 = e2.length, i2 = new Array(o2);
e2.forEach(function(e3, t3) {
return K.resolve(e3).then(function(e4) {
return n2(e4);
}, function(e4) {
i2[t3] = e4, --o2 || r2(new AggregateError(i2));
});
});
});
}), Ae.withResolvers) && (K.withResolvers = Ae.withResolvers);
var i = { awaits: 0, echoes: 0, id: 0 }, He = 0, Je = [], Ze = 0, et = 0, tt = 0;
function v(e2, t3, n2, r2) {
var o2 = P, i2 = Object.create(o2), t3 = (i2.parent = o2, i2.ref = 0, i2.global = false, i2.id = ++tt, s.env, i2.env = Ce ? { Promise: K, PromiseProp: { value: K, configurable: true, writable: true }, all: K.all, race: K.race, allSettled: K.allSettled, any: K.any, resolve: K.resolve, reject: K.reject } : {}, t3 && a(i2, t3), ++o2.ref, i2.finalize = function() {
--this.parent.ref || this.parent.finalize();
}, at(i2, e2, n2, r2));
return 0 === i2.ref && i2.finalize(), t3;
}
function nt() {
return i.id || (i.id = ++He), ++i.awaits, i.echoes += Ke, i.id;
}
function w() {
return !!i.awaits && (0 == --i.awaits && (i.id = 0), i.echoes = i.awaits * Ke, true);
}
function rt(e2) {
return i.echoes && e2 && e2.constructor === Ae ? (nt(), e2.then(function(e3) {
return w(), e3;
}, function(e3) {
return w(), S(e3);
})) : e2;
}
function ot() {
var e2 = Je[Je.length - 1];
Je.pop(), h(e2, false);
}
function h(e2, t3) {
var n2, r2, o2 = P;
(t3 ? !i.echoes || Ze++ && e2 === P : !Ze || --Ze && e2 === P) || queueMicrotask(t3 ? (function(e3) {
++et, i.echoes && 0 != --i.echoes || (i.echoes = i.awaits = i.id = 0), Je.push(P), h(e3, true);
}).bind(null, e2) : ot), e2 !== P && (P = e2, o2 === s && (s.env = it()), Ce) && (n2 = s.env.Promise, r2 = e2.env, o2.global || e2.global) && (Object.defineProperty(f, "Promise", r2.PromiseProp), n2.all = r2.all, n2.race = r2.race, n2.resolve = r2.resolve, n2.reject = r2.reject, r2.allSettled && (n2.allSettled = r2.allSettled), r2.any) && (n2.any = r2.any);
}
function it() {
var e2 = f.Promise;
return Ce ? { Promise: e2, PromiseProp: Object.getOwnPropertyDescriptor(f, "Promise"), all: e2.all, race: e2.race, allSettled: e2.allSettled, any: e2.any, resolve: e2.resolve, reject: e2.reject } : {};
}
function at(e2, t3, n2, r2, o2) {
var i2 = P;
try {
return h(e2, true), t3(n2, r2, o2);
} finally {
h(i2, false);
}
}
function ut(t3, n2, r2, o2) {
return "function" != typeof t3 ? t3 : function() {
var e2 = P;
r2 && nt(), h(n2, true);
try {
return t3.apply(this, arguments);
} finally {
h(e2, false), o2 && queueMicrotask(w);
}
};
}
function st(e2) {
Promise === Ae && 0 === i.echoes ? 0 === Ze ? e2() : enqueueNativeMicroTask(e2) : setTimeout(e2, 0);
}
-1 === ("" + Se).indexOf("[native code]") && (nt = w = g);
var S = K.reject;
var ct = String.fromCharCode(65535), A = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.", lt = "String expected.", ft = "__dbnames", ht = "readonly", dt = "readwrite";
function pt(e2, t3) {
return e2 ? t3 ? function() {
return e2.apply(this, arguments) && t3.apply(this, arguments);
} : e2 : t3;
}
var yt = { type: 3, lower: -1 / 0, lowerOpen: false, upper: [[]], upperOpen: false };
function vt(t3) {
return "string" != typeof t3 || /\./.test(t3) ? function(e2) {
return e2;
} : function(e2) {
return void 0 === e2[t3] && t3 in e2 && delete (e2 = ee(e2))[t3], e2;
};
}
function mt() {
throw k.Type("Entity instances must never be new:ed. Instances are generated by the framework bypassing the constructor.");
}
function C(e2, t3) {
try {
var n2 = bt(e2), r2 = bt(t3);
if (n2 !== r2) return "Array" === n2 ? 1 : "Array" === r2 ? -1 : "binary" === n2 ? 1 : "binary" === r2 ? -1 : "string" === n2 ? 1 : "string" === r2 ? -1 : "Date" === n2 ? 1 : "Date" !== r2 ? NaN : -1;
switch (n2) {
case "number":
case "Date":
case "string":
return t3 < e2 ? 1 : e2 < t3 ? -1 : 0;
case "binary":
for (var o2 = gt(e2), i2 = gt(t3), a2 = o2.length, u2 = i2.length, s2 = a2 < u2 ? a2 : u2, c2 = 0; c2 < s2; ++c2) if (o2[c2] !== i2[c2]) return o2[c2] < i2[c2] ? -1 : 1;
return a2 === u2 ? 0 : a2 < u2 ? -1 : 1;
case "Array":
for (var l2 = e2, f2 = t3, h2 = l2.length, d2 = f2.length, p2 = h2 < d2 ? h2 : d2, y2 = 0; y2 < p2; ++y2) {
var v2 = C(l2[y2], f2[y2]);
if (0 !== v2) return v2;
}
return h2 === d2 ? 0 : h2 < d2 ? -1 : 1;
}
} catch (e3) {
}
return NaN;
}
function bt(e2) {
var t3 = typeof e2;
return "object" == t3 && (ArrayBuffer.isView(e2) || "ArrayBuffer" === (t3 = ne(e2))) ? "binary" : t3;
}
function gt(e2) {
return e2 instanceof Uint8Array ? e2 : ArrayBuffer.isView(e2) ? new Uint8Array(e2.buffer, e2.byteOffset, e2.byteLength) : new Uint8Array(e2);
}
function wt(t3, n2, r2) {
var e2 = t3.schema.yProps;
return e2 ? (n2 && 0 < r2.numFailures && (n2 = n2.filter(function(e3, t4) {
return !r2.failures[t4];
})), Promise.all(e2.map(function(e3) {
e3 = e3.updatesTable;
return n2 ? t3.db.table(e3).where("k").anyOf(n2).delete() : t3.db.table(e3).clear();
})).then(function() {
return r2;
})) : r2;
}
xt.prototype.execute = function(e2) {
var t3 = this["@@propmod"];
if (void 0 !== t3.add) {
var n2 = t3.add;
if (x(n2)) return R(R([], x(e2) ? e2 : [], true), n2).sort();
if ("number" == typeof n2) return (Number(e2) || 0) + n2;
if ("bigint" == typeof n2) try {
return BigInt(e2) + n2;
} catch (e3) {
return BigInt(0) + n2;
}
throw new TypeError("Invalid term ".concat(n2));
}
if (void 0 !== t3.remove) {
var r2 = t3.remove;
if (x(r2)) return x(e2) ? e2.filter(function(e3) {
return !r2.includes(e3);
}).sort() : [];
if ("number" == typeof r2) return Number(e2) - r2;
if ("bigint" == typeof r2) try {
return BigInt(e2) - r2;
} catch (e3) {
return BigInt(0) - r2;
}
throw new TypeError("Invalid subtrahend ".concat(r2));
}
n2 = null == (n2 = t3.replacePrefix) ? void 0 : n2[0];
return n2 && "string" == typeof e2 && e2.startsWith(n2) ? t3.replacePrefix[1] + e2.substring(n2.length) : e2;
};
var _t = xt;
function xt(e2) {
this["@@propmod"] = e2;
}
function kt(e2, t3) {
for (var n2 = O(t3), r2 = n2.length, o2 = false, i2 = 0; i2 < r2; ++i2) {
var a2 = n2[i2], u2 = t3[a2], s2 = c(e2, a2);
u2 instanceof _t ? (b(e2, a2, u2.execute(s2)), o2 = true) : s2 !== u2 && (b(e2, a2, u2), o2 = true);
}
return o2;
}
r.prototype._trans = function(e2, r2, t3) {
var n2 = this._tx || P.trans, o2 = this.name, i2 = l && "undefined" != typeof console && console.createTask && console.createTask("Dexie: ".concat("readonly" === e2 ? "read" : "write", " ").concat(this.name));
function a2(e3, t4, n3) {
if (n3.schema[o2]) return r2(n3.idbtrans, n3);
throw new k.NotFound("Table " + o2 + " not part of transaction");
}
var u2 = $e();
try {
var s2 = n2 && n2.db._novip === this.db._novip ? n2 === P.trans ? n2._promise(e2, a2, t3) : v(function() {
return n2._promise(e2, a2, t3);
}, { trans: n2, transless: P.transless || P }) : (function t4(n3, r3, o3, i3) {
if (n3.idbdb && (n3._state.openComplete || P.letThrough || n3._vip)) {
var a3 = n3._createTransaction(r3, o3, n3._dbSchema);
try {
a3.create(), n3._state.PR1398_maxLoop = 3;
} catch (e3) {
return e3.name === de.InvalidState && n3.isOpen() && 0 < --n3._state.PR1398_maxLoop ? (console.warn("Dexie: Need to reopen db"), n3.close({ disableAutoOpen: false }), n3.open().then(function() {
return t4(n3, r3, o3, i3);
})) : S(e3);
}
return a3._promise(r3, function(e3, t5) {
return v(function() {
return P.trans = a3, i3(e3, t5, a3);
});
}).then(function(e3) {
if ("readwrite" === r3) try {
a3.idbtrans.commit();
} catch (e4) {
}
return "readonly" === r3 ? e3 : a3._completion.then(function() {
return e3;
});
});
}
if (n3._state.openComplete) return S(new k.DatabaseClosed(n3._state.dbOpenError));
if (!n3._state.isBeingOpened) {
if (!n3._state.autoOpen) return S(new k.DatabaseClosed());
n3.open().catch(g);
}
return n3._state.dbReadyPromise.then(function() {
return t4(n3, r3, o3, i3);
});
})(this.db, e2, [this.name], a2);
return i2 && (s2._consoleTask = i2, s2 = s2.catch(function(e3) {
return console.trace(e3), S(e3);
})), s2;
} finally {
u2 && Qe();
}
}, r.prototype.get = function(t3, e2) {
var n2 = this;
return t3 && t3.constructor === Object ? this.where(t3).first(e2) : null == t3 ? S(new k.Type("Invalid argument to Table.get()")) : this._trans("readonly", function(e3) {
return n2.core.get({ trans: e3, key: t3 }).then(function(e4) {
return n2.hook.reading.fire(e4);
});
}).then(e2);
}, r.prototype.where = function(i2) {
if ("string" == typeof i2) return new this.db.WhereClause(this, i2);
if (x(i2)) return new this.db.WhereClause(this, "[".concat(i2.join("+"), "]"));
var n2 = O(i2);
if (1 === n2.length) return this.where(n2[0]).equals(i2[n2[0]]);
var e2 = this.schema.indexes.concat(this.schema.primKey).filter(function(t4) {
if (t4.compound && n2.every(function(e4) {
return 0 <= t4.keyPath.indexOf(e4);
})) {
for (var e3 = 0; e3 < n2.length; ++e3) if (-1 === n2.indexOf(t4.keyPath[e3])) return false;
return true;
}
return false;
}).sort(function(e3, t4) {
return e3.keyPath.length - t4.keyPath.length;
})[0];
if (e2 && this.db._maxKey !== ct) return t3 = e2.keyPath.slice(0, n2.length), this.where(t3).equals(t3.map(function(e3) {
return i2[e3];
}));
!e2 && l && console.warn("The query ".concat(JSON.stringify(i2), " on ").concat(this.name, " would benefit from a ") + "compound index [".concat(n2.join("+"), "]"));
var a2 = this.schema.idxByName;
function u2(e3, t4) {
return 0 === C(e3, t4);
}
var t3 = n2.reduce(function(e3, t4) {
var n3 = e3[0], e3 = e3[1], r3 = a2[t4], o2 = i2[t4];
return [n3 || r3, n3 || !r3 ? pt(e3, r3 && r3.multi ? function(e4) {
e4 = c(e4, t4);
return x(e4) && e4.some(function(e5) {
return u2(o2, e5);
});
} : function(e4) {
return u2(o2, c(e4, t4));
}) : e3];
}, [null, null]), r2 = t3[0], t3 = t3[1];
return r2 ? this.where(r2.name).equals(i2[r2.keyPath]).filter(t3) : e2 ? this.filter(t3) : this.where(n2).equals("");
}, r.prototype.filter = function(e2) {
return this.toCollection().and(e2);
}, r.prototype.count = function(e2) {
return this.toCollection().count(e2);
}, r.prototype.offset = function(e2) {
return this.toCollection().offset(e2);
}, r.prototype.limit = function(e2) {
return this.toCollection().limit(e2);
}, r.prototype.each = function(e2) {
return this.toCollection().each(e2);
}, r.prototype.toArray = function(e2) {
return this.toCollection().toArray(e2);
}, r.prototype.toCollection = function() {
return new this.db.Collection(new this.db.WhereClause(this));
}, r.prototype.orderBy = function(e2) {
return new this.db.Collection(new this.db.WhereClause(this, x(e2) ? "[".concat(e2.join("+"), "]") : e2));
}, r.prototype.reverse = function() {
return this.toCollection().reverse();
}, r.prototype.mapToClass = function(r2) {
for (var i2 = this.db, a2 = this.name, o2 = ((this.schema.mappedClass = r2).prototype instanceof mt && (r2 = ((e3) => {
var t4 = o3, n2 = e3;
if ("function" != typeof n2 && null !== n2) throw new TypeError("Class extends value " + String(n2) + " is not a constructor or null");
function r3() {
this.constructor = t4;
}
function o3() {
return null !== e3 && e3.apply(this, arguments) || this;
}
return B(t4, n2), t4.prototype = null === n2 ? Object.create(n2) : (r3.prototype = n2.prototype, new r3()), Object.defineProperty(o3.prototype, "db", { get: function() {
return i2;
}, enumerable: false, configurable: true }), o3.prototype.table = function() {
return a2;
}, o3;
})(r2)), new Set()), e2 = r2.prototype; e2; e2 = F(e2)) Object.getOwnPropertyNames(e2).forEach(function(e3) {
return o2.add(e3);
});
function t3(e3) {
if (!e3) return e3;
var t4, n2 = Object.create(r2.prototype);
for (t4 in e3) if (!o2.has(t4)) try {
n2[t4] = e3[t4];
} catch (e4) {
}
return n2;
}
return this.schema.readHook && this.hook.reading.unsubscribe(this.schema.readHook), this.schema.readHook = t3, this.hook("reading", t3), r2;
}, r.prototype.defineClass = function() {
return this.mapToClass(function(e2) {
a(this, e2);
});
}, r.prototype.add = function(t3, n2) {
var r2 = this, e2 = this.schema.primKey, o2 = e2.auto, i2 = e2.keyPath, a2 = t3;
return i2 && o2 && (a2 = vt(i2)(t3)), this._trans("readwrite", function(e3) {
return r2.core.mutate({ trans: e3, type: "add", keys: null != n2 ? [n2] : null, values: [a2] });
}).then(function(e3) {
return e3.numFailures ? K.reject(e3.failures[0]) : e3.lastResult;
}).then(function(e3) {
if (i2) try {
b(t3, i2, e3);
} catch (e4) {
}
return e3;
});
}, r.prototype.upsert = function(r2, o2) {
var i2 = this, a2 = this.schema.primKey.keyPath;
return this._trans("readwrite", function(n2) {
return i2.core.get({ trans: n2, key: r2 }).then(function(t3) {
var e2 = null != t3 ? t3 : {};
return kt(e2, o2), a2 && b(e2, a2, r2), i2.core.mutate({ trans: n2, type: "put", values: [e2], keys: [r2], upsert: true, updates: { keys: [r2], changeSpecs: [o2] } }).then(function(e3) {
return e3.numFailures ? K.reject(e3.failures[0]) : !!t3;
});
});
});
}, r.prototype.update = function(e2, t3) {
return "object" != typeof e2 || x(e2) ? this.where(":id").equals(e2).modify(t3) : void 0 === (e2 = c(e2, this.schema.primKey.keyPath)) ? S(new k.InvalidArgument("Given object does not contain its primary key")) : this.where(":id").equals(e2).modify(t3);
}, r.prototype.put = function(t3, n2) {
var r2 = this, e2 = this.schema.primKey, o2 = e2.auto, i2 = e2.keyPath, a2 = t3;
return i2 && o2 && (a2 = vt(i2)(t3)), this._trans("readwrite", function(e3) {
return r2.core.mutate({ trans: e3, type: "put", values: [a2], keys: null != n2 ? [n2] : null });
}).then(function(e3) {
return e3.numFailures ? K.reject(e3.failures[0]) : e3.lastResult;
}).then(function(e3) {
if (i2) try {
b(t3, i2, e3);
} catch (e4) {
}
return e3;
});
}, r.prototype.delete = function(t3) {
var n2 = this;
return this._trans("readwrite", function(e2) {
return n2.core.mutate({ trans: e2, type: "delete", keys: [t3] }).then(function(e3) {
return wt(n2, [t3], e3);
}).then(function(e3) {
return e3.numFailures ? K.reject(e3.failures[0]) : void 0;
});
});
}, r.prototype.clear = function() {
var t3 = this;
return this._trans("readwrite", function(e2) {
return t3.core.mutate({ trans: e2, type: "deleteRange", range: yt }).then(function(e3) {
return wt(t3, null, e3);
});
}).then(function(e2) {
return e2.numFailures ? K.reject(e2.failures[0]) : void 0;
});
}, r.prototype.bulkGet = function(t3) {
var n2 = this;
return this._trans("readonly", function(e2) {
return n2.core.getMany({ keys: t3, trans: e2 }).then(function(e3) {
return e3.map(function(e4) {
return n2.hook.reading.fire(e4);
});
});
});
}, r.prototype.bulkAdd = function(o2, e2, t3) {
var i2 = this, a2 = Array.isArray(e2) ? e2 : void 0, u2 = (t3 = t3 || (a2 ? void 0 : e2)) ? t3.allKeys : void 0;
return this._trans("readwrite", function(e3) {
var t4 = i2.schema.primKey, n2 = t4.auto, t4 = t4.keyPath;
if (t4 && a2) throw new k.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");
if (a2 && a2.length !== o2.length) throw new k.InvalidArgument("Arguments objects and keys must have the same length");
var r2 = o2.length, n2 = t4 && n2 ? o2.map(vt(t4)) : o2;
return i2.core.mutate({ trans: e3, type: "add", keys: a2, values: n2, wantResults: u2 }).then(function(e4) {
var t5 = e4.numFailures, n3 = e4.failures;
if (0 === t5) return u2 ? e4.results : e4.lastResult;
throw new he("".concat(i2.name, ".bulkAdd(): ").concat(t5, " of ").concat(r2, " operations failed"), n3);
});
});
}, r.prototype.bulkPut = function(o2, e2, t3) {
var i2 = this, a2 = Array.isArray(e2) ? e2 : void 0, u2 = (t3 = t3 || (a2 ? void 0 : e2)) ? t3.allKeys : void 0;
return this._trans("readwrite", function(e3) {
var t4 = i2.schema.primKey, n2 = t4.auto, t4 = t4.keyPath;
if (t4 && a2) throw new k.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");
if (a2 && a2.length !== o2.length) throw new k.InvalidArgument("Arguments objects and keys must have the same length");
var r2 = o2.length, n2 = t4 && n2 ? o2.map(vt(t4)) : o2;
return i2.core.mutate({ trans: e3, type: "put", keys: a2, values: n2, wantResults: u2 }).then(function(e4) {
var t5 = e4.numFailures, n3 = e4.failures;
if (0 === t5) return u2 ? e4.results : e4.lastResult;
throw new he("".concat(i2.name, ".bulkPut(): ").concat(t5, " of ").concat(r2, " operations failed"), n3);
});
});
}, r.prototype.bulkUpdate = function(t3) {
var h2 = this, n2 = this.core, r2 = t3.map(function(e2) {
return e2.key;
}), o2 = t3.map(function(e2) {
return e2.changes;
}), d2 = [];
return this._trans("readwrite", function(e2) {
return n2.getMany({ trans: e2, keys: r2, cache: "clone" }).then(function(c2) {
var l2 = [], f2 = [], s2 = (t3.forEach(function(e3, t4) {
var n3 = e3.key, r3 = e3.changes, o3 = c2[t4];
if (o3) {
for (var i2 = 0, a2 = Object.keys(r3); i2 < a2.length; i2++) {
var u2 = a2[i2], s3 = r3[u2];
if (u2 === h2.schema.primKey.keyPath) {
if (0 !== C(s3, n3)) throw new k.Constraint("Cannot update primary key in bulkUpdate()");
} else b(o3, u2, s3);
}
d2.push(t4), l2.push(n3), f2.push(o3);
}
}), l2.length);
return n2.mutate({ trans: e2, type: "put", keys: l2, values: f2, updates: { keys: r2, changeSpecs: o2 } }).then(function(e3) {
var t4 = e3.numFailures, n3 = e3.failures;
if (0 === t4) return s2;
for (var r3 = 0, o3 = Object.keys(n3); r3 < o3.length; r3++) {
var i2, a2 = o3[r3], u2 = d2[Number(a2)];
null != u2 && (i2 = n3[a2], delete n3[a2], n3[u2] = i2);
}
throw new he("".concat(h2.name, ".bulkUpdate(): ").concat(t4, " of ").concat(s2, " operations failed"), n3);
});
});
});
}, r.prototype.bulkDelete = function(t3) {
var r2 = this, o2 = t3.length;
return this._trans("readwrite", function(e2) {
return r2.core.mutate({ trans: e2, type: "delete", keys: t3 }).then(function(e3) {
return wt(r2, t3, e3);
});
}).then(function(e2) {
var t4 = e2.numFailures, n2 = e2.failures;
if (0 === t4) return e2.lastResult;
throw new he("".concat(r2.name, ".bulkDelete(): ").concat(t4, " of ").concat(o2, " operations failed"), n2);
});
};
var Ot = r;
function r() {
}
function Pt(o2) {
function t3(e3, t4) {
if (t4) {
for (var n3 = arguments.length, r2 = new Array(n3 - 1); --n3; ) r2[n3 - 1] = arguments[n3];
return a2[e3].subscribe.apply(null, r2), o2;
}
if ("string" == typeof e3) return a2[e3];
}
var a2 = {};
t3.addEventType = u2;
for (var e2 = 1, n2 = arguments.length; e2 < n2; ++e2) u2(arguments[e2]);
return t3;
function u2(e3, n3, r2) {
var o3, i2;
if ("object" != typeof e3) return n3 = n3 || xe, i2 = { subscribers: [], fire: r2 = r2 || g, subscribe: function(e4) {
-1 === i2.subscribers.indexOf(e4) && (i2.subscribers.push(e4), i2.fire = n3(i2.fire, e4));
}, unsubscribe: function(t4) {
i2.subscribers = i2.subscribers.filter(function(e4) {
return e4 !== t4;
}), i2.fire = i2.subscribers.reduce(n3, r2);
} }, a2[e3] = t3[e3] = i2;
O(o3 = e3).forEach(function(e4) {
var t4 = o3[e4];
if (x(t4)) u2(e4, o3[e4][0], o3[e4][1]);
else {
if ("asap" !== t4) throw new k.InvalidArgument("Invalid event config");
var n4 = u2(e4, ve, function() {
for (var e5 = arguments.length, t5 = new Array(e5); e5--; ) t5[e5] = arguments[e5];
n4.subscribers.forEach(function(e6) {
Q(function() {
e6.apply(null, t5);
});
});
});
}
});
}
}
function Kt(e2, t3) {
return U(t3).from({ prototype: e2 }), t3;
}
function Et(e2, t3) {
return !(e2.filter || e2.algorithm || e2.or) && (t3 ? e2.justLimit : !e2.replayFilter);
}
function St(e2, t3) {
e2.filter = pt(e2.filter, t3);
}
function At(e2, t3, n2) {
var r2 = e2.replayFilter;
e2.replayFilter = r2 ? function() {
return pt(r2(), t3());
} : t3, e2.justLimit = n2 && !r2;
}
function Ct(e2, t3) {
if (e2.isPrimKey) return t3.primaryKey;
var n2 = t3.getIndexByKeyPath(e2.index);
if (n2) return n2;
throw new k.Schema("KeyPath " + e2.index + " on object store " + t3.name + " is not indexed");
}
function jt(e2, t3, n2) {
var r2 = Ct(e2, t3.schema);
return t3.openCursor({ trans: n2, values: !e2.keysOnly, reverse: "prev" === e2.dir, unique: !!e2.unique, query: { index: r2, range: e2.range } });
}
function Tt(e2, i2, t3, n2) {
var a2, r2, u2 = e2.replayFilter ? pt(e2.filter, e2.replayFilter()) : e2.filter;
return e2.or ? (a2 = {}, r2 = function(e3, t4, n3) {
var r3, o2;
u2 && !u2(t4, n3, function(e4) {
return t4.stop(e4);
}, function(e4) {
return t4.fail(e4);
}) || ("[object ArrayBuffer]" === (o2 = "" + (r3 = t4.primaryKey)) && (o2 = "" + new Uint8Array(r3)), m(a2, o2)) || (a2[o2] = true, i2(e3, t4, n3));
}, Promise.all([e2.or._iterate(r2, t3), It(jt(e2, n2, t3), e2.algorithm, r2, !e2.keysOnly && e2.valueMapper)])) : It(jt(e2, n2, t3), pt(e2.algorithm, u2), i2, !e2.keysOnly && e2.valueMapper);
}
function It(e2, r2, o2, i2) {
var a2 = E(i2 ? function(e3, t3, n2) {
return o2(i2(e3), t3, n2);
} : o2);
return e2.then(function(n2) {
if (n2) return n2.start(function() {
var t3 = function() {
return n2.continue();
};
r2 && !r2(n2, function(e3) {
return t3 = e3;
}, function(e3) {
n2.stop(e3), t3 = g;
}, function(e3) {
n2.fail(e3), t3 = g;
}) || a2(n2.value, n2, function(e3) {
return t3 = e3;
}), t3();
});
});
}
o.prototype._read = function(e2, t3) {
var n2 = this._ctx;
return n2.error ? n2.table._trans(null, S.bind(null, n2.error)) : n2.table._trans("readonly", e2).then(t3);
}, o.prototype._write = function(e2) {
var t3 = this._ctx;
return t3.error ? t3.table._trans(null, S.bind(null, t3.error)) : t3.table._trans("readwrite", e2, "locked");
}, o.prototype._addAlgorithm = function(e2) {
var t3 = this._ctx;
t3.algorithm = pt(t3.algorithm, e2);
}, o.prototype._iterate = function(e2, t3) {
return Tt(this._ctx, e2, t3, this._ctx.table.core);
}, o.prototype.clone = function(e2) {
var t3 = Object.create(this.constructor.prototype), n2 = Object.create(this._ctx);
return e2 && a(n2, e2), t3._ctx = n2, t3;
}, o.prototype.raw = function() {
return this._ctx.valueMapper = null, this;
}, o.prototype.each = function(t3) {
var n2 = this._ctx;
return this._read(function(e2) {
return Tt(n2, t3, e2, n2.table.core);
});
}, o.prototype.count = function(e2) {
var o2 = this;
return this._read(function(e3) {
var t3, n2 = o2._ctx, r2 = n2.table.core;
return Et(n2, true) ? r2.count({ trans: e3, query: { index: Ct(n2, r2.schema), range: n2.range } }).then(function(e4) {
return Math.min(e4, n2.limit);
}) : (t3 = 0, Tt(n2, function() {
return ++t3, false;
}, e3, r2).then(function() {
return t3;
}));
}).then(e2);
}, o.prototype.sortBy = function(e2, t3) {
var n2 = e2.split(".").reverse(), r2 = n2[0], o2 = n2.length - 1;
function i2(e3, t4) {
return t4 ? i2(e3[n2[t4]], t4 - 1) : e3[r2];
}
var a2 = "next" === this._ctx.dir ? 1 : -1;
function u2(e3, t4) {
return C(i2(e3, o2), i2(t4, o2)) * a2;
}
return this.toArray(function(e3) {
return e3.sort(u2);
}).then(t3);
}, o.prototype.toArray = function(e2) {
var i2 = this;
return this._read(function(e3) {
var t3, n2, r2, o2 = i2._ctx;
return Et(o2, true) && 0 < o2.limit ? (t3 = o2.valueMapper, n2 = Ct(o2, o2.table.core.schema), o2.table.core.query({ trans: e3, limit: o2.limit, values: true, direction: "prev" === o2.dir ? "prev" : void 0, query: { index: n2, range: o2.range } }).then(function(e4) {
e4 = e4.result;
return t3 ? e4.map(t3) : e4;
})) : (r2 = [], Tt(o2, function(e4) {
return r2.push(e4);
}, e3, o2.table.core).then(function() {
return r2;
}));
}, e2);
}, o.prototype.offset = function(t3) {
var e2 = this._ctx;
return t3 <= 0 || (e2.offset += t3, Et(e2) ? At(e2, function() {
var n2 = t3;
return function(e3, t4) {
return 0 === n2 || (1 === n2 ? --n2 : t4(function() {
e3.advance(n2), n2 = 0;
}), false);
};
}) : At(e2, function() {
var e3 = t3;
return function() {
return --e3 < 0;
};
})), this;
}, o.prototype.limit = function(e2) {
return this._ctx.limit = Math.min(this._ctx.limit, e2), At(this._ctx, function() {
var r2 = e2;
return function(e3, t3, n2) {
return --r2 <= 0 && t3(n2), 0 <= r2;
};
}, true), this;
}, o.prototype.until = function(r2, o2) {
return St(this._ctx, function(e2, t3, n2) {
return !r2(e2.value) || (t3(n2), o2);
}), this;
}, o.prototype.first = function(e2) {
return this.limit(1).toArray(function(e3) {
return e3[0];
}).then(e2);
}, o.prototype.last = function(e2) {
return this.reverse().first(e2);
}, o.prototype.filter = function(t3) {
var e2;
return St(this._ctx, function(e3) {
return t3(e3.value);
}), (e2 = this._ctx).isMatch = pt(e2.isMatch, t3), this;
}, o.prototype.and = function(e2) {
return this.filter(e2);
}, o.prototype.or = function(e2) {
return new this.db.WhereClause(this._ctx.table, e2, this);
}, o.prototype.reverse = function() {
return this._ctx.dir = "prev" === this._ctx.dir ? "next" : "prev", this._ondirectionchange && this._ondirectionchange(this._ctx.dir), this;
}, o.prototype.desc = function() {
return this.reverse();
}, o.prototype.eachKey = function(n2) {
var e2 = this._ctx;
return e2.keysOnly = !e2.isMatch, this.each(function(e3, t3) {
n2(t3.key, t3);
});
}, o.prototype.eachUniqueKey = function(e2) {
return this._ctx.unique = "unique", this.eachKey(e2);
}, o.prototype.eachPrimaryKey = function(n2) {
var e2 = this._ctx;
return e2.keysOnly = !e2.isMatch, this.each(function(e3, t3) {
n2(t3.primaryKey, t3);
});
}, o.prototype.keys = function(e2) {
var t3 = this._ctx, n2 = (t3.keysOnly = !t3.isMatch, []);
return this.each(function(e3, t4) {
n2.push(t4.key);
}).then(function() {
return n2;
}).then(e2);
}, o.prototype.primaryKeys = function(e2) {
var n2 = this._ctx;
if (Et(n2, true) && 0 < n2.limit) return this._read(function(e3) {
var t3 = Ct(n2, n2.table.core.schema);
return n2.table.core.query({ trans: e3, values: false, limit: n2.limit, direction: "prev" === n2.dir ? "prev" : void 0, query: { index: t3, range: n2.range } });
}).then(function(e3) {
return e3.result;
}).then(e2);
n2.keysOnly = !n2.isMatch;
var r2 = [];
return this.each(function(e3, t3) {
r2.push(t3.primaryKey);
}).then(function() {
return r2;
}).then(e2);
}, o.prototype.uniqueKeys = function(e2) {
return this._ctx.unique = "unique", this.keys(e2);
}, o.prototype.firstKey = function(e2) {
return this.limit(1).keys(function(e3) {
return e3[0];
}).then(e2);
}, o.prototype.lastKey = function(e2) {
return this.reverse().firstKey(e2);
}, o.prototype.distinct = function() {
var n2, e2 = this._ctx, e2 = e2.index && e2.table.schema.idxByName[e2.index];
return e2 && e2.multi && (n2 = {}, St(this._ctx, function(e3) {
var e3 = e3.primaryKey.toString(), t3 = m(n2, e3);
return n2[e3] = true, !t3;
})), this;
}, o.prototype.modify = function(x2) {
var n2 = this, k2 = this._ctx;
return this._write(function(p2) {
function y2(e3, t4) {
var n3 = t4.failures;
u2 += e3 - t4.numFailures;
for (var r2 = 0, o2 = O(n3); r2 < o2.length; r2++) {
var i2 = o2[r2];
a2.push(n3[i2]);
}
}
var v2 = "function" == typeof x2 ? x2 : function(e3) {
return kt(e3, x2);
}, m2 = k2.table.core, e2 = m2.schema.primaryKey, b2 = e2.outbound, g2 = e2.extractKey, w2 = 200, e2 = n2.db._options.modifyChunkSize, a2 = (e2 && (w2 = "object" == typeof e2 ? e2[m2.name] || e2["*"] || 200 : e2), []), u2 = 0, t3 = [], _2 = x2 === Dt;
return n2.clone().primaryKeys().then(function(f2) {
function h2(s2) {
var c2 = Math.min(w2, f2.length - s2), l2 = f2.slice(s2, s2 + c2);
return (_2 ? Promise.resolve([]) : m2.getMany({ trans: p2, keys: l2, cache: "immutable" })).then(function(e3) {
var n3 = [], t4 = [], r2 = b2 ? [] : null, o2 = _2 ? l2 : [];
if (!_2) for (var i2 = 0; i2 < c2; ++i2) {
var a3 = e3[i2], u3 = { value: ee(a3), primKey: f2[s2 + i2] };
false !== v2.call(u3, u3.value, u3) && (null == u3.value ? o2.push(f2[s2 + i2]) : b2 || 0 === C(g2(a3), g2(u3.value)) ? (t4.push(u3.value), b2 && r2.push(f2[s2 + i2])) : (o2.push(f2[s2 + i2]), n3.push(u3.value)));
}
return Promise.resolve(0 < n3.length && m2.mutate({ trans: p2, type: "add", values: n3 }).then(function(e4) {
for (var t5 in e4.failures) o2.splice(parseInt(t5), 1);
y2(n3.length, e4);
})).then(function() {
return (0 < t4.length || d2 && "object" == typeof x2) && m2.mutate({ trans: p2, type: "put", keys: r2, values: t4, criteria: d2, changeSpec: "function" != typeof x2 && x2, isAdditionalChunk: 0 < s2 }).then(function(e4) {
return y2(t4.length, e4);
});
}).then(function() {
return (0 < o2.length || d2 && _2) && m2.mutate({ trans: p2, type: "delete", keys: o2, criteria: d2, isAdditionalChunk: 0 < s2 }).then(function(e4) {
return wt(k2.table, o2, e4);
}).then(function(e4) {
return y2(o2.length, e4);
});
}).then(function() {
return f2.length > s2 + c2 && h2(s2 + w2);
});
});
}
var d2 = Et(k2) && k2.limit === 1 / 0 && ("function" != typeof x2 || _2) && { index: k2.index, range: k2.range };
return h2(0).then(function() {
if (0 < a2.length) throw new fe("Error modifying one or more objects", a2, u2, t3);
return f2.length;
});
});
});
}, o.prototype.delete = function() {
var o2 = this._ctx, n2 = o2.range;
return !Et(o2) || o2.table.schema.yProps || !o2.isPrimKey && 3 !== n2.type ? this.modify(Dt) : this._write(function(e2) {
var t3 = o2.table.core.schema.primaryKey, r2 = n2;
return o2.table.core.count({ trans: e2, query: { index: t3, range: r2 } }).then(function(n3) {
return o2.table.core.mutate({ trans: e2, type: "deleteRange", range: r2 }).then(function(e3) {
var t4 = e3.failures, e3 = e3.numFailures;
if (e3) throw new fe("Could not delete some values", Object.keys(t4).map(function(e4) {
return t4[e4];
}), n3 - e3);
return n3 - e3;
});
});
});
};
var qt = o;
function o() {
}
var Dt = function(e2, t3) {
return t3.value = null;
};
function Bt(e2, t3) {
return e2 < t3 ? -1 : e2 === t3 ? 0 : 1;
}
function Rt(e2, t3) {
return t3 < e2 ? -1 : e2 === t3 ? 0 : 1;
}
function j(e2, t3, n2) {
e2 = e2 instanceof Lt ? new e2.Collection(e2) : e2;
return e2._ctx.error = new (n2 || TypeError)(t3), e2;
}
function Ft(e2) {
return new e2.Collection(e2, function() {
return Mt("");
}).limit(0);
}
function Nt(e2, s2, n2, r2) {
var o2, c2, l2, f2, h2, d2, p2, y2 = n2.length;
if (!n2.every(function(e3) {
return "string" == typeof e3;
})) return j(e2, lt);
function t3(e3) {
o2 = "next" === e3 ? function(e4) {
return e4.toUpperCase();
} : function(e4) {
return e4.toLowerCase();
}, c2 = "next" === e3 ? function(e4) {
return e4.toLowerCase();
} : function(e4) {
return e4.toUpperCase();
}, l2 = "next" === e3 ? Bt : Rt;
var t4 = n2.map(function(e4) {
return { lower: c2(e4), upper: o2(e4) };
}).sort(function(e4, t5) {
return l2(e4.lower, t5.lower);
});
f2 = t4.map(function(e4) {
return e4.upper;
}), h2 = t4.map(function(e4) {
return e4.lower;
}), p2 = "next" === (d2 = e3) ? "" : r2;
}
t3("next");
var e2 = new e2.Collection(e2, function() {
return T(f2[0], h2[y2 - 1] + r2);
}), v2 = (e2._ondirectionchange = function(e3) {
t3(e3);
}, 0);
return e2._addAlgorithm(function(e3, t4, n3) {
var r3 = e3.key;
if ("string" == typeof r3) {
var o3 = c2(r3);
if (s2(o3, h2, v2)) return true;
for (var i2 = null, a2 = v2; a2 < y2; ++a2) {
var u2 = ((e4, t5, n4, r4, o4, i3) => {
for (var a3 = Math.min(e4.length, r4.length), u3 = -1, s3 = 0; s3 < a3; ++s3) {
var c3 = t5[s3];
if (c3 !== r4[s3]) return o4(e4[s3], n4[s3]) < 0 ? e4.substr(0, s3) + n4[s3] + n4.substr(s3 + 1) : o4(e4[s3], r4[s3]) < 0 ? e4.substr(0, s3) + r4[s3] + n4.substr(s3 + 1) : 0 <= u3 ? e4.substr(0, u3) + t5[u3] + n4.substr(u3 + 1) : null;
o4(e4[s3], c3) < 0 && (u3 = s3);
}
return a3 < r4.length && "next" === i3 ? e4 + n4.substr(e4.length) : a3 < e4.length && "prev" === i3 ? e4.substr(0, n4.length) : u3 < 0 ? null : e4.substr(0, u3) + r4[u3] + n4.substr(u3 + 1);
})(r3, o3, f2[a2], h2[a2], l2, d2);
null === u2 && null === i2 ? v2 = a2 + 1 : (null === i2 || 0 < l2(i2, u2)) && (i2 = u2);
}
t4(null !== i2 ? function() {
e3.continue(i2 + p2);
} : n3);
}
return false;
}), e2;
}
function T(e2, t3, n2, r2) {
return { type: 2, lower: e2, upper: t3, lowerOpen: n2, upperOpen: r2 };
}
function Mt(e2) {
return { type: 1, lower: e2, upper: e2 };
}
Object.defineProperty(d.prototype, "Collection", { get: function() {
return this._ctx.table.db.Collection;
}, enumerable: false, configurable: true }), d.prototype.between = function(e2, t3, n2, r2) {
n2 = false !== n2, r2 = true === r2;
try {
return 0 < this._cmp(e2, t3) || 0 === this._cmp(e2, t3) && (n2 || r2) && (!n2 || !r2) ? Ft(this) : new this.Collection(this, function() {
return T(e2, t3, !n2, !r2);
});
} catch (e3) {
return j(this, A);
}
}, d.prototype.equals = function(e2) {
return null == e2 ? j(this, A) : new this.Collection(this, function() {
return Mt(e2);
});
}, d.prototype.above = function(e2) {
return null == e2 ? j(this, A) : new this.Collection(this, function() {
return T(e2, void 0, true);
});
}, d.prototype.aboveOrEqual = function(e2) {
return null == e2 ? j(this, A) : new this.Collection(this, function() {
return T(e2, void 0, false);
});
}, d.prototype.below = function(e2) {
return null == e2 ? j(this, A) : new this.Collection(this, function() {
return T(void 0, e2, false, true);
});
}, d.prototype.belowOrEqual = function(e2) {
return null == e2 ? j(this, A) : new this.Collection(this, function() {
return T(void 0, e2);
});
}, d.prototype.startsWith = function(e2) {
return "string" != typeof e2 ? j(this, lt) : this.between(e2, e2 + ct, true, true);
}, d.prototype.startsWithIgnoreCase = function(e2) {
return "" === e2 ? this.startsWith(e2) : Nt(this, function(e3, t3) {
return 0 === e3.indexOf(t3[0]);
}, [e2], ct);
}, d.prototype.equalsIgnoreCase = function(e2) {
return Nt(this, function(e3, t3) {
return e3 === t3[0];
}, [e2], "");
}, d.prototype.anyOfIgnoreCase = function() {
var e2 = n.apply(ae, arguments);
return 0 === e2.length ? Ft(this) : Nt(this, function(e3, t3) {
return -1 !== t3.indexOf(e3);
}, e2, "");
}, d.prototype.startsWithAnyOfIgnoreCase = function() {
var e2 = n.apply(ae, arguments);
return 0 === e2.length ? Ft(this) : Nt(this, function(t3, e3) {
return e3.some(function(e4) {
return 0 === t3.indexOf(e4);
});
}, e2, ct);
}, d.prototype.anyOf = function() {
var e2, o2, t3 = this, i2 = n.apply(ae, arguments), a2 = this._cmp;
try {
i2.sort(a2);
} catch (e3) {
return j(this, A);
}
return 0 === i2.length ? Ft(this) : ((e2 = new this.Collection(this, function() {
return T(i2[0], i2[i2.length - 1]);
}))._ondirectionchange = function(e3) {
a2 = "next" === e3 ? t3._ascending : t3._descending, i2.sort(a2);
}, o2 = 0, e2._addAlgorithm(function(e3, t4, n2) {
for (var r2 = e3.key; 0 < a2(r2, i2[o2]); ) if (++o2 === i2.length) return t4(n2), false;
return 0 === a2(r2, i2[o2]) || (t4(function() {
e3.continue(i2[o2]);
}), false);
}), e2);
}, d.prototype.notEqual = function(e2) {
return this.inAnyRange([[-1 / 0, e2], [e2, this.db._maxKey]], { includeLowers: false, includeUppers: false });
}, d.prototype.noneOf = function() {
var e2 = n.apply(ae, arguments);
if (0 === e2.length) return new this.Collection(this);
try {
e2.sort(this._ascending);
} catch (e3) {
return j(this, A);
}
var t3 = e2.reduce(function(e3, t4) {
return e3 ? e3.concat([[e3[e3.length - 1][1], t4]]) : [[-1 / 0, t4]];
}, null);
return t3.push([e2[e2.length - 1], this.db._maxKey]), this.inAnyRange(t3, { includeLowers: false, includeUppers: false });
}, d.prototype.inAnyRange = function(e2, t3) {
var i2 = this, a2 = this._cmp, u2 = this._ascending, n2 = this._descending, s2 = this._min, c2 = this._max;
if (0 === e2.length) return Ft(this);
if (!e2.every(function(e3) {
return void 0 !== e3[0] && void 0 !== e3[1] && u2(e3[0], e3[1]) <= 0;
})) return j(this, "First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower", k.InvalidArgument);
var r2 = !t3 || false !== t3.includeLowers, o2 = t3 && true === t3.includeUppers;
var l2, f2 = u2;
function h2(e3, t4) {
return f2(e3[0], t4[0]);
}
try {
(l2 = e2.reduce(function(e3, t4) {
for (var n3 = 0, r3 = e3.length; n3 < r3; ++n3) {
var o3 = e3[n3];
if (a2(t4[0], o3[1]) < 0 && 0 < a2(t4[1], o3[0])) {
o3[0] = s2(o3[0], t4[0]), o3[1] = c2(o3[1], t4[1]);
break;
}
}
return n3 === r3 && e3.push(t4), e3;
}, [])).sort(h2);
} catch (e3) {
return j(this, A);
}
var d2 = 0, p2 = o2 ? function(e3) {
return 0 < u2(e3, l2[d2][1]);
} : function(e3) {
return 0 <= u2(e3, l2[d2][1]);
}, y2 = r2 ? function(e3) {
return 0 < n2(e3, l2[d2][0]);
} : function(e3) {
return 0 <= n2(e3, l2[d2][0]);
};
var v2 = p2, t3 = new this.Collection(this, function() {
return T(l2[0][0], l2[l2.length - 1][1], !r2, !o2);
});
return t3._ondirectionchange = function(e3) {
f2 = "next" === e3 ? (v2 = p2, u2) : (v2 = y2, n2), l2.sort(h2);
}, t3._addAlgorithm(function(e3, t4, n3) {
for (var r3, o3 = e3.key; v2(o3); ) if (++d2 === l2.length) return t4(n3), false;
return !p2(r3 = o3) && !y2(r3) || (0 === i2._cmp(o3, l2[d2][1]) || 0 === i2._cmp(o3, l2[d2][0]) || t4(function() {
f2 === u2 ? e3.continue(l2[d2][0]) : e3.continue(l2[d2][1]);
}), false);
}), t3;
}, d.prototype.startsWithAnyOf = function() {
var e2 = n.apply(ae, arguments);
return e2.every(function(e3) {
return "string" == typeof e3;
}) ? 0 === e2.length ? Ft(this) : this.inAnyRange(e2.map(function(e3) {
return [e3, e3 + ct];
})) : j(this, "startsWithAnyOf() only works with strings");
};
var Lt = d;
function d() {
}
function I(t3) {
return E(function(e2) {
return Ut(e2), t3(e2.target.error), false;
});
}
function Ut(e2) {
e2.stopPropagation && e2.stopPropagation(), e2.preventDefault && e2.preventDefault();
}
var zt = "storagemutated", Vt = "x-storagemutated-1", Wt = Pt(null, zt), Yt = (p.prototype._lock = function() {
return $(!P.global), ++this._reculock, 1 !== this._reculock || P.global || (P.lockOwnerFor = this), this;
}, p.prototype._unlock = function() {
if ($(!P.global), 0 == --this._reculock) for (P.global || (P.lockOwnerFor = null); 0 < this._blockedFuncs.length && !this._locked(); ) {
var e2 = this._blockedFuncs.shift();
try {
at(e2[1], e2[0]);
} catch (e3) {
}
}
return this;
}, p.prototype._locked = function() {
return this._reculock && P.lockOwnerFor !== this;
}, p.prototype.create = function(t3) {
var n2 = this;
if (this.mode) {
var e2 = this.db.idbdb, r2 = this.db._state.dbOpenError;
if ($(!this.idbtrans), !t3 && !e2) switch (r2 && r2.name) {
case "DatabaseClosedError":
throw new k.DatabaseClosed(r2);
case "MissingAPIError":
throw new k.MissingAPI(r2.message, r2);
default:
throw new k.OpenFailed(r2);
}
if (!this.active) throw new k.TransactionInactive();
$(null === this._completion._state), (t3 = this.idbtrans = t3 || (this.db.core || e2).transaction(this.storeNames, this.mode, { durability: this.chromeTransactionDurability })).onerror = E(function(e3) {
Ut(e3), n2._reject(t3.error);
}), t3.onabort = E(function(e3) {
Ut(e3), n2.active && n2._reject(new k.Abort(t3.error)), n2.active = false, n2.on("abort").fire(e3);
}), t3.oncomplete = E(function() {
n2.active = false, n2._resolve(), "mutatedParts" in t3 && Wt.storagemutated.fire(t3.mutatedParts);
});
}
return this;
}, p.prototype._promise = function(n2, r2, o2) {
var e2, i2 = this;
return "readwrite" === n2 && "readwrite" !== this.mode ? S(new k.ReadOnly("Transaction is readonly")) : this.active ? this._locked() ? new K(function(e3, t3) {
i2._blockedFuncs.push([function() {
i2._promise(n2, r2, o2).then(e3, t3);
}, P]);
}) : o2 ? v(function() {
var e3 = new K(function(e4, t3) {
i2._lock();
var n3 = r2(e4, t3, i2);
n3 && n3.then && n3.then(e4, t3);
});
return e3.finally(function() {
return i2._unlock();
}), e3._lib = true, e3;
}) : ((e2 = new K(function(e3, t3) {
var n3 = r2(e3, t3, i2);
n3 && n3.then && n3.then(e3, t3);
}))._lib = true, e2) : S(new k.TransactionInactive());
}, p.prototype._root = function() {
return this.parent ? this.parent._root() : this;
}, p.prototype.waitFor = function(e2) {
var t3, r2 = this._root(), o2 = K.resolve(e2), i2 = (r2._waitingFor ? r2._waitingFor = r2._waitingFor.then(function() {
return o2;
}) : (r2._waitingFor = o2, r2._waitingQueue = [], t3 = r2.idbtrans.objectStore(r2.storeNames[0]), (function e3() {
for (++r2._spinCount; r2._waitingQueue.length; ) r2._waitingQueue.shift()();
r2._waitingFor && (t3.get(-1 / 0).onsuccess = e3);
})()), r2._waitingFor);
return new K(function(t4, n2) {
o2.then(function(e3) {
return r2._waitingQueue.push(E(t4.bind(null, e3)));
}, function(e3) {
return r2._waitingQueue.push(E(n2.bind(null, e3)));
}).finally(function() {
r2._waitingFor === i2 && (r2._waitingFor = null);
});
});
}, p.prototype.abort = function() {
this.active && (this.active = false, this.idbtrans && this.idbtrans.abort(), this._reject(new k.Abort()));
}, p.prototype.table = function(e2) {
var t3 = this._memoizedTables || (this._memoizedTables = {});
if (m(t3, e2)) return t3[e2];
var n2 = this.schema[e2];
if (n2) return (n2 = new this.db.Table(e2, n2, this)).core = this.db.core.table(e2), t3[e2] = n2;
throw new k.NotFound("Table " + e2 + " not part of transaction");
}, p);
function p() {
}
function $t(e2, t3, n2, r2, o2, i2, a2, u2) {
return { name: e2, keyPath: t3, unique: n2, multi: r2, auto: o2, compound: i2, src: (n2 && !a2 ? "&" : "") + (r2 ? "*" : "") + (o2 ? "++" : "") + Qt(t3), type: u2 };
}
function Qt(e2) {
return "string" == typeof e2 ? e2 : e2 ? "[" + [].join.call(e2, "+") + "]" : "";
}
function Gt(e2, t3, n2) {
return { name: e2, primKey: t3, indexes: n2, mappedClass: null, idxByName: (r2 = function(e3) {
return [e3.name, e3];
}, n2.reduce(function(e3, t4, n3) {
t4 = r2(t4, n3);
return t4 && (e3[t4[0]] = t4[1]), e3;
}, {})) };
var r2;
}
var Xt = function(e2) {
try {
return e2.only([[]]), Xt = function() {
return [[]];
}, [[]];
} catch (e3) {
return Xt = function() {
return ct;
}, ct;
}
};
function Ht(t3) {
return null == t3 ? function() {
} : "string" == typeof t3 ? 1 === (n2 = t3).split(".").length ? function(e2) {
return e2[n2];
} : function(e2) {
return c(e2, n2);
} : function(e2) {
return c(e2, t3);
};
var n2;
}
function Jt(e2) {
return [].slice.call(e2);
}
var Zt = 0;
function en(e2) {
return null == e2 ? ":id" : "string" == typeof e2 ? e2 : "[".concat(e2.join("+"), "]");
}
function tn(e2, o2, t3) {
function _2(e3) {
if (3 === e3.type) return null;
if (4 === e3.type) throw new Error("Cannot convert never type to IDBKeyRange");
var t4 = e3.lower, n3 = e3.upper, r3 = e3.lowerOpen, e3 = e3.upperOpen;
return void 0 === t4 ? void 0 === n3 ? null : o2.upperBound(n3, !!e3) : void 0 === n3 ? o2.lowerBound(t4, !!r3) : o2.bound(t4, n3, !!r3, !!e3);
}
function n2(e3) {
var p2, y2, w2 = e3.name;
return { name: w2, schema: e3, mutate: function(e4) {
var y3 = e4.trans, v2 = e4.type, m2 = e4.keys, b2 = e4.values, g2 = e4.range;
return new Promise(function(t4, e5) {
t4 = E(t4);
var n3 = y3.objectStore(w2), r3 = null == n3.keyPath, o3 = "put" === v2 || "add" === v2;
if (!o3 && "delete" !== v2 && "deleteRange" !== v2) throw new Error("Invalid operation type: " + v2);
var i3, a3 = (m2 || b2 || { length: 1 }).length;
if (m2 && b2 && m2.length !== b2.length) throw new Error("Given keys array must have same length as given values array.");
if (0 === a3) return t4({ numFailures: 0, failures: {}, results: [], lastResult: void 0 });
function u3(e6) {
++l2, Ut(e6);
}
var s3 = [], c3 = [], l2 = 0;
if ("deleteRange" === v2) {
if (4 === g2.type) return t4({ numFailures: l2, failures: c3, results: [], lastResult: void 0 });
3 === g2.type ? s3.push(i3 = n3.clear()) : s3.push(i3 = n3.delete(_2(g2)));
} else {
var r3 = o3 ? r3 ? [b2, m2] : [b2, null] : [m2, null], f2 = r3[0], h2 = r3[1];
if (o3) for (var d2 = 0; d2 < a3; ++d2) s3.push(i3 = h2 && void 0 !== h2[d2] ? n3[v2](f2[d2], h2[d2]) : n3[v2](f2[d2])), i3.onerror = u3;
else for (d2 = 0; d2 < a3; ++d2) s3.push(i3 = n3[v2](f2[d2])), i3.onerror = u3;
}
function p3(e6) {
e6 = e6.target.result, s3.forEach(function(e7, t5) {
return null != e7.error && (c3[t5] = e7.error);
}), t4({ numFailures: l2, failures: c3, results: "delete" === v2 ? m2 : s3.map(function(e7) {
return e7.result;
}), lastResult: e6 });
}
i3.onerror = function(e6) {
u3(e6), p3(e6);
}, i3.onsuccess = p3;
});
}, getMany: function(e4) {
var f2 = e4.trans, h2 = e4.keys;
return new Promise(function(t4, e5) {
t4 = E(t4);
for (var n3, r3 = f2.objectStore(w2), o3 = h2.length, i3 = new Array(o3), a3 = 0, u3 = 0, s3 = function(e6) {
e6 = e6.target;
i3[e6._pos] = e6.result, ++u3 === a3 && t4(i3);
}, c3 = I(e5), l2 = 0; l2 < o3; ++l2) null != h2[l2] && ((n3 = r3.get(h2[l2]))._pos = l2, n3.onsuccess = s3, n3.onerror = c3, ++a3);
0 === a3 && t4(i3);
});
}, get: function(e4) {
var r3 = e4.trans, o3 = e4.key;
return new Promise(function(t4, e5) {
t4 = E(t4);
var n3 = r3.objectStore(w2).get(o3);
n3.onsuccess = function(e6) {
return t4(e6.target.result);
}, n3.onerror = I(e5);
});
}, query: (p2 = a2, y2 = u2, function(d2) {
return new Promise(function(t4, e4) {
t4 = E(t4);
var n3, r3, o3, i3, a3 = d2.trans, u3 = d2.values, s3 = d2.limit, c3 = d2.query, l2 = null != (l2 = d2.direction) ? l2 : "next", f2 = s3 === 1 / 0 ? void 0 : s3, h2 = c3.index, c3 = c3.range, a3 = a3.objectStore(w2), a3 = h2.isPrimaryKey ? a3 : a3.index(h2.name), h2 = _2(c3);
if (0 === s3) return t4({ result: [] });
y2 ? (c3 = { query: h2, count: f2, direction: l2 }, (n3 = u3 ? a3.getAll(c3) : a3.getAllKeys(c3)).onsuccess = function(e5) {
return t4({ result: e5.target.result });
}, n3.onerror = I(e4)) : p2 && "next" === l2 ? ((n3 = u3 ? a3.getAll(h2, f2) : a3.getAllKeys(h2, f2)).onsuccess = function(e5) {
return t4({ result: e5.target.result });
}, n3.onerror = I(e4)) : (r3 = 0, o3 = !u3 && "openKeyCursor" in a3 ? a3.openKeyCursor(h2, l2) : a3.openCursor(h2, l2), i3 = [], o3.onsuccess = function() {
var e5 = o3.result;
return !e5 || (i3.push(u3 ? e5.value : e5.primaryKey), ++r3 === s3) ? t4({ result: i3 }) : void e5.continue();
}, o3.onerror = I(e4));
});
}), openCursor: function(e4) {
var c3 = e4.trans, i3 = e4.values, a3 = e4.query, u3 = e4.reverse, l2 = e4.unique;
return new Promise(function(t4, n3) {
t4 = E(t4);
var e5 = a3.index, r3 = a3.range, o3 = c3.objectStore(w2), o3 = e5.isPrimaryKey ? o3 : o3.index(e5.name), e5 = u3 ? l2 ? "prevunique" : "prev" : l2 ? "nextunique" : "next", s3 = !i3 && "openKeyCursor" in o3 ? o3.openKeyCursor(_2(r3), e5) : o3.openCursor(_2(r3), e5);
s3.onerror = I(n3), s3.onsuccess = E(function(e6) {
var r4, o4, i4, a4, u4 = s3.result;
u4 ? (u4.___id = ++Zt, u4.done = false, r4 = u4.continue.bind(u4), o4 = (o4 = u4.continuePrimaryKey) && o4.bind(u4), i4 = u4.advance.bind(u4), a4 = function() {
throw new Error("Cursor not stopped");
}, u4.trans = c3, u4.stop = u4.continue = u4.continuePrimaryKey = u4.advance = function() {
throw new Error("Cursor not started");
}, u4.fail = E(n3), u4.next = function() {
var e7 = this, t5 = 1;
return this.start(function() {
return t5-- ? e7.continue() : e7.stop();
}).then(function() {
return e7;
});
}, u4.start = function(e7) {
function t5() {
if (s3.result) try {
e7();
} catch (e8) {
u4.fail(e8);
}
else u4.done = true, u4.start = function() {
throw new Error("Cursor behind last entry");
}, u4.stop();
}
var n4 = new Promise(function(t6, e8) {
t6 = E(t6), s3.onerror = I(e8), u4.fail = e8, u4.stop = function(e9) {
u4.stop = u4.continue = u4.continuePrimaryKey = u4.advance = a4, t6(e9);
};
});
return s3.onsuccess = E(function(e8) {
s3.onsuccess = t5, t5();
}), u4.continue = r4, u4.continuePrimaryKey = o4, u4.advance = i4, t5(), n4;
}, t4(u4)) : t4(null);
}, n3);
});
}, count: function(e4) {
var t4 = e4.query, o3 = e4.trans, i3 = t4.index, a3 = t4.range;
return new Promise(function(t5, e5) {
var n3 = o3.objectStore(w2), n3 = i3.isPrimaryKey ? n3 : n3.index(i3.name), r3 = _2(a3), r3 = r3 ? n3.count(r3) : n3.count();
r3.onsuccess = E(function(e6) {
return t5(e6.target.result);
}), r3.onerror = I(e5);
});
} };
}
r2 = t3, i2 = Jt((t3 = e2).objectStoreNames), s2 = 0 < i2.length ? r2.objectStore(i2[0]) : {};
var r2, t3 = { schema: { name: t3.name, tables: i2.map(function(e3) {
return r2.objectStore(e3);
}).map(function(t4) {
var e3 = t4.keyPath, n3 = t4.autoIncrement, r3 = x(e3), o3 = {}, r3 = { name: t4.name, primaryKey: { name: null, isPrimaryKey: true, outbound: null == e3, compound: r3, keyPath: e3, autoIncrement: n3, unique: true, extractKey: Ht(e3) }, indexes: Jt(t4.indexNames).map(function(e4) {
return t4.index(e4);
}).map(function(e4) {
var t5 = e4.name, n4 = e4.unique, r4 = e4.multiEntry, e4 = e4.keyPath, t5 = { name: t5, compound: x(e4), keyPath: e4, unique: n4, multiEntry: r4, extractKey: Ht(e4) };
return o3[en(e4)] = t5;
}), getIndexByKeyPath: function(e4) {
return o3[en(e4)];
} };
return o3[":id"] = r3.primaryKey, null != e3 && (o3[en(e3)] = r3.primaryKey), r3;
}) }, hasGetAll: 0 < i2.length && "getAll" in s2 && !("undefined" != typeof navigator && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604), hasIdb3Features: "getAllRecords" in s2 }, i2 = t3.schema, a2 = t3.hasGetAll, u2 = t3.hasIdb3Features, s2 = i2.tables.map(n2), c2 = {};
return s2.forEach(function(e3) {
return c2[e3.name] = e3;
}), { stack: "dbcore", transaction: e2.transaction.bind(e2), table: function(e3) {
if (c2[e3]) return c2[e3];
throw new Error("Table '".concat(e3, "' not found"));
}, MIN_KEY: -1 / 0, MAX_KEY: Xt(o2), schema: i2 };
}
function nn(e2, t3, n2, r2) {
n2 = n2.IDBKeyRange;
return t3 = tn(t3, n2, r2), { dbcore: e2.dbcore.reduce(function(e3, t4) {
t4 = t4.create;
return _(_({}, e3), t4(e3));
}, t3) };
}
function rn(n2, e2) {
var t3 = e2.db, t3 = nn(n2._middlewares, t3, n2._deps, e2);
n2.core = t3.dbcore, n2.tables.forEach(function(e3) {
var t4 = e3.name;
n2.core.schema.tables.some(function(e4) {
return e4.name === t4;
}) && (e3.core = n2.core.table(t4), n2[t4] instanceof n2.Table) && (n2[t4].core = e3.core);
});
}
function on(o2, e2, t3, i2) {
t3.forEach(function(n2) {
var r2 = i2[n2];
e2.forEach(function(e3) {
var t4 = (function e4(t5, n3) {
return z(t5, n3) || (t5 = F(t5)) && e4(t5, n3);
})(e3, n2);
(!t4 || "value" in t4 && void 0 === t4.value) && (e3 === o2.Transaction.prototype || e3 instanceof o2.Transaction ? u(e3, n2, { get: function() {
return this.table(n2);
}, set: function(e4) {
L(this, n2, { value: e4, writable: true, configurable: true, enumerable: true });
} }) : e3[n2] = new o2.Table(n2, r2));
});
});
}
function an(n2, e2) {
e2.forEach(function(e3) {
for (var t3 in e3) e3[t3] instanceof n2.Table && delete e3[t3];
});
}
function un(e2, t3) {
return e2._cfg.version - t3._cfg.version;
}
function sn(n2, r2, o2, e2) {
var i2 = n2._dbSchema, a2 = (o2.objectStoreNames.contains("$meta") && !i2.$meta && (i2.$meta = Gt("$meta", vn("")[0], []), n2._storeNames.push("$meta")), n2._createTransaction("readwrite", n2._storeNames, i2)), u2 = (a2.create(o2), a2._completion.catch(e2), a2._reject.bind(a2)), s2 = P.transless || P;
v(function() {
if (P.trans = a2, P.transless = s2, 0 !== r2) return rn(n2, o2), t3 = r2, ((e3 = a2).storeNames.includes("$meta") ? e3.table("$meta").get("version").then(function(e4) {
return null != e4 ? e4 : t3;
}) : K.resolve(t3)).then(function(e4) {
var s3 = n2, c2 = e4, l2 = a2, f2 = o2, t4 = [], e4 = s3._versions, h2 = s3._dbSchema = pn(0, s3.idbdb, f2);
return 0 === (e4 = e4.filter(function(e5) {
return e5._cfg.version >= c2;
})).length ? K.resolve() : (e4.forEach(function(u3) {
t4.push(function() {
var t5, n3, r3, o3 = h2, e5 = u3._cfg.dbschema, i3 = (yn(s3, o3, f2), yn(s3, e5, f2), h2 = s3._dbSchema = e5, ln(o3, e5)), a3 = (i3.add.forEach(function(e6) {
fn(f2, e6[0], e6[1].primKey, e6[1].indexes);
}), i3.change.forEach(function(e6) {
if (e6.recreate) throw new k.Upgrade("Not yet support for changing primary key");
var t6 = f2.objectStore(e6.name);
e6.add.forEach(function(e7) {
return dn(t6, e7);
}), e6.change.forEach(function(e7) {
t6.deleteIndex(e7.name), dn(t6, e7);
}), e6.del.forEach(function(e7) {
return t6.deleteIndex(e7);
});
}), u3._cfg.contentUpgrade);
if (a3 && u3._cfg.version > c2) return rn(s3, f2), l2._memoizedTables = {}, t5 = G(e5), i3.del.forEach(function(e6) {
t5[e6] = o3[e6];
}), an(s3, [s3.Transaction.prototype]), on(s3, [s3.Transaction.prototype], O(t5), t5), l2.schema = t5, (n3 = ue(a3)) && nt(), e5 = K.follow(function() {
var e6;
(r3 = a3(l2)) && n3 && (e6 = w.bind(null, null), r3.then(e6, e6));
}), r3 && "function" == typeof r3.then ? K.resolve(r3) : e5.then(function() {
return r3;
});
}), t4.push(function(e5) {
var t5, n3, r3 = u3._cfg.dbschema;
t5 = r3, n3 = e5, [].slice.call(n3.db.objectStoreNames).forEach(function(e6) {
return null == t5[e6] && n3.db.deleteObjectStore(e6);
}), an(s3, [s3.Transaction.prototype]), on(s3, [s3.Transaction.prototype], s3._storeNames, s3._dbSchema), l2.schema = s3._dbSchema;
}), t4.push(function(e5) {
s3.idbdb.objectStoreNames.contains("$meta") && (Math.ceil(s3.idbdb.version / 10) === u3._cfg.version ? (s3.idbdb.deleteObjectStore("$meta"), delete s3._dbSchema.$meta, s3._storeNames = s3._storeNames.filter(function(e6) {
return "$meta" !== e6;
})) : e5.objectStore("$meta").put(u3._cfg.version, "version"));
});
}), (function e5() {
return t4.length ? K.resolve(t4.shift()(l2.idbtrans)).then(e5) : K.resolve();
})().then(function() {
hn(h2, f2);
}));
}).catch(u2);
var e3, t3;
O(i2).forEach(function(e4) {
fn(o2, e4, i2[e4].primKey, i2[e4].indexes);
}), rn(n2, o2), K.follow(function() {
return n2.on.populate.fire(a2);
}).catch(u2);
});
}
function cn(e2, r2) {
hn(e2._dbSchema, r2), r2.db.version % 10 != 0 || r2.objectStoreNames.contains("$meta") || r2.db.createObjectStore("$meta").add(Math.ceil(r2.db.version / 10 - 1), "version");
var t3 = pn(0, e2.idbdb, r2);
yn(e2, e2._dbSchema, r2);
for (var n2 = 0, o2 = ln(t3, e2._dbSchema).change; n2 < o2.length; n2++) {
var i2 = ((t4) => {
if (t4.change.length || t4.recreate) return console.warn("Unable to patch indexes of table ".concat(t4.name, " because it has changes on the type of index or primary key.")), { value: void 0 };
var n3 = r2.objectStore(t4.name);
t4.add.forEach(function(e3) {
l && console.debug("Dexie upgrade patch: Creating missing index ".concat(t4.name, ".").concat(e3.src)), dn(n3, e3);
});
})(o2[n2]);
if ("object" == typeof i2) return i2.value;
}
}
function ln(e2, t3) {
var n2, r2 = { del: [], add: [], change: [] };
for (n2 in e2) t3[n2] || r2.del.push(n2);
for (n2 in t3) {
var o2 = e2[n2], i2 = t3[n2];
if (o2) {
var a2 = { name: n2, def: i2, recreate: false, del: [], add: [], change: [] };
if ("" + (o2.primKey.keyPath || "") != "" + (i2.primKey.keyPath || "") || o2.primKey.auto !== i2.primKey.auto) a2.recreate = true, r2.change.push(a2);
else {
var u2 = o2.idxByName, s2 = i2.idxByName, c2 = void 0;
for (c2 in u2) s2[c2] || a2.del.push(c2);
for (c2 in s2) {
var l2 = u2[c2], f2 = s2[c2];
l2 ? l2.src !== f2.src && a2.change.push(f2) : a2.add.push(f2);
}
(0 < a2.del.length || 0 < a2.add.length || 0 < a2.change.length) && r2.change.push(a2);
}
} else r2.add.push([n2, i2]);
}
return r2;
}
function fn(e2, t3, n2, r2) {
var o2 = e2.db.createObjectStore(t3, n2.keyPath ? { keyPath: n2.keyPath, autoIncrement: n2.auto } : { autoIncrement: n2.auto });
r2.forEach(function(e3) {
return dn(o2, e3);
});
}
function hn(t3, n2) {
O(t3).forEach(function(e2) {
n2.db.objectStoreNames.contains(e2) || (l && console.debug("Dexie: Creating missing table", e2), fn(n2, e2, t3[e2].primKey, t3[e2].indexes));
});
}
function dn(e2, t3) {
e2.createIndex(t3.name, t3.keyPath, { unique: t3.unique, multiEntry: t3.multi });
}
function pn(e2, t3, u2) {
var s2 = {};
return W(t3.objectStoreNames, 0).forEach(function(e3) {
for (var t4 = u2.objectStore(e3), n2 = $t(Qt(a2 = t4.keyPath), a2 || "", true, false, !!t4.autoIncrement, a2 && "string" != typeof a2, true), r2 = [], o2 = 0; o2 < t4.indexNames.length; ++o2) {
var i2 = t4.index(t4.indexNames[o2]), a2 = i2.keyPath, i2 = $t(i2.name, a2, !!i2.unique, !!i2.multiEntry, false, a2 && "string" != typeof a2, false);
r2.push(i2);
}
s2[e3] = Gt(e3, n2, r2);
}), s2;
}
function yn(e2, t3, n2) {
for (var r2 = n2.db.objectStoreNames, o2 = 0; o2 < r2.length; ++o2) {
var i2 = r2[o2], a2 = n2.objectStore(i2);
e2._hasGetAll = "getAll" in a2;
for (var u2 = 0; u2 < a2.indexNames.length; ++u2) {
var s2, c2 = a2.indexNames[u2], l2 = a2.index(c2).keyPath, l2 = "string" == typeof l2 ? l2 : "[" + W(l2).join("+") + "]";
t3[i2] && (s2 = t3[i2].idxByName[l2]) && (s2.name = c2, delete t3[i2].idxByName[l2], t3[i2].idxByName[c2] = s2);
}
}
"undefined" != typeof navigator && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && f.WorkerGlobalScope && f instanceof f.WorkerGlobalScope && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604 && (e2._hasGetAll = false);
}
function vn(e2) {
return e2.split(",").map(function(e3, t3) {
var n2 = e3.split(":"), r2 = null == (r2 = n2[1]) ? void 0 : r2.trim(), n2 = (e3 = n2[0].trim()).replace(/([&*]|\+\+)/g, ""), o2 = /^\[/.test(n2) ? n2.match(/^\[(.*)\]$/)[1].split("+") : n2;
return $t(n2, o2 || null, /\&/.test(e3), /\*/.test(e3), /\+\+/.test(e3), x(o2), 0 === t3, r2);
});
}
bn.prototype._createTableSchema = Gt, bn.prototype._parseIndexSyntax = vn, bn.prototype._parseStoresSpec = function(r2, o2) {
var i2 = this;
O(r2).forEach(function(e2) {
if (null !== r2[e2]) {
var t3 = i2._parseIndexSyntax(r2[e2]), n2 = t3.shift();
if (!n2) throw new k.Schema("Invalid schema for table " + e2 + ": " + r2[e2]);
if (n2.unique = true, n2.multi) throw new k.Schema("Primary key cannot be multiEntry*");
t3.forEach(function(e3) {
if (e3.auto) throw new k.Schema("Only primary key can be marked as autoIncrement (++)");
if (!e3.keyPath) throw new k.Schema("Index must have a name and cannot be an empty string");
});
n2 = i2._createTableSchema(e2, n2, t3);
o2[e2] = n2;
}
});
}, bn.prototype.stores = function(e2) {
var t3 = this.db, e2 = (this._cfg.storesSource = this._cfg.storesSource ? a(this._cfg.storesSource, e2) : e2, t3._versions), n2 = {}, r2 = {};
return e2.forEach(function(e3) {
a(n2, e3._cfg.storesSource), r2 = e3._cfg.dbschema = {}, e3._parseStoresSpec(n2, r2);
}), t3._dbSchema = r2, an(t3, [t3._allTables, t3, t3.Transaction.prototype]), on(t3, [t3._allTables, t3, t3.Transaction.prototype, this._cfg.tables], O(r2), r2), t3._storeNames = O(r2), this;
}, bn.prototype.upgrade = function(e2) {
return this._cfg.contentUpgrade = ke(this._cfg.contentUpgrade || g, e2), this;
};
var mn = bn;
function bn() {
}
var gn = (() => {
var o2, i2, t3;
return "undefined" != typeof FinalizationRegistry && "undefined" != typeof WeakRef ? (o2 = new Set(), i2 = new FinalizationRegistry(function(e2) {
o2.delete(e2);
}), { toArray: function() {
return Array.from(o2).map(function(e2) {
return e2.deref();
}).filter(function(e2) {
return void 0 !== e2;
});
}, add: function(e2) {
var t4 = new WeakRef(e2._novip);
o2.add(t4), i2.register(e2._novip, t4, t4), o2.size > e2._options.maxConnections && (t4 = o2.values().next().value, o2.delete(t4), i2.unregister(t4));
}, remove: function(e2) {
if (e2) for (var t4 = o2.values(), n2 = t4.next(); !n2.done; ) {
var r2 = n2.value;
if (r2.deref() === e2._novip) return o2.delete(r2), void i2.unregister(r2);
n2 = t4.next();
}
} }) : (t3 = [], { toArray: function() {
return t3;
}, add: function(e2) {
t3.push(e2._novip);
}, remove: function(e2) {
e2 && -1 !== (e2 = t3.indexOf(e2._novip)) && t3.splice(e2, 1);
} });
})();
function wn(e2, t3) {
var n2 = e2._dbNamesDB;
return n2 || (n2 = e2._dbNamesDB = new y(ft, { addons: [], indexedDB: e2, IDBKeyRange: t3 })).version(1).stores({ dbnames: "name" }), n2.table("dbnames");
}
function _n(e2) {
return e2 && "function" == typeof e2.databases;
}
function xn(e2) {
return v(function() {
return P.letThrough = true, e2();
});
}
function kn(e2) {
return !("from" in e2);
}
var q = function(e2, t3) {
var n2;
if (!this) return n2 = new q(), e2 && "d" in e2 && a(n2, e2), n2;
a(this, arguments.length ? { d: 1, from: e2, to: 1 < arguments.length ? t3 : e2 } : { d: 0 });
};
function On(e2, t3, n2) {
var r2 = C(t3, n2);
if (!isNaN(r2)) {
if (0 < r2) throw RangeError();
if (kn(e2)) return a(e2, { from: t3, to: n2, d: 1 });
var r2 = e2.l, o2 = e2.r;
if (C(n2, e2.from) < 0) return r2 ? On(r2, t3, n2) : e2.l = { from: t3, to: n2, d: 1, l: null, r: null }, Sn(e2);
if (0 < C(t3, e2.to)) return o2 ? On(o2, t3, n2) : e2.r = { from: t3, to: n2, d: 1, l: null, r: null }, Sn(e2);
C(t3, e2.from) < 0 && (e2.from = t3, e2.l = null, e2.d = o2 ? o2.d + 1 : 1), 0 < C(n2, e2.to) && (e2.to = n2, e2.r = null, e2.d = e2.l ? e2.l.d + 1 : 1);
t3 = !e2.r;
r2 && !e2.l && Pn(e2, r2), o2 && t3 && Pn(e2, o2);
}
}
function Pn(e2, t3) {
kn(t3) || (function e3(t4, n2) {
var r2 = n2.from, o2 = n2.l, i2 = n2.r;
On(t4, r2, n2.to), o2 && e3(t4, o2), i2 && e3(t4, i2);
})(e2, t3);
}
function Kn(e2, t3) {
var n2 = En(t3), r2 = n2.next();
if (!r2.done) for (var o2 = r2.value, i2 = En(e2), a2 = i2.next(o2.from), u2 = a2.value; !r2.done && !a2.done; ) {
if (C(u2.from, o2.to) <= 0 && 0 <= C(u2.to, o2.from)) return true;
C(o2.from, u2.from) < 0 ? o2 = (r2 = n2.next(u2.from)).value : u2 = (a2 = i2.next(o2.from)).value;
}
return false;
}
function En(e2) {
var n2 = kn(e2) ? null : { s: 0, n: e2 };
return { next: function(e3) {
for (var t3 = 0 < arguments.length; n2; ) switch (n2.s) {
case 0:
if (n2.s = 1, t3) for (; n2.n.l && C(e3, n2.n.from) < 0; ) n2 = { up: n2, n: n2.n.l, s: 1 };
else for (; n2.n.l; ) n2 = { up: n2, n: n2.n.l, s: 1 };
case 1:
if (n2.s = 2, !t3 || C(e3, n2.n.to) <= 0) return { value: n2.n, done: false };
case 2:
if (n2.n.r) {
n2.s = 3, n2 = { up: n2, n: n2.n.r, s: 0 };
continue;
}
case 3:
n2 = n2.up;
}
return { done: true };
} };
}
function Sn(e2) {
var t3, n2, r2, o2 = ((null == (o2 = e2.r) ? void 0 : o2.d) || 0) - ((null == (o2 = e2.l) ? void 0 : o2.d) || 0), o2 = 1 < o2 ? "r" : o2 < -1 ? "l" : "";
o2 && (t3 = "r" == o2 ? "l" : "r", n2 = _({}, e2), r2 = e2[o2], e2.from = r2.from, e2.to = r2.to, e2[o2] = r2[o2], n2[o2] = r2[t3], (e2[t3] = n2).d = An(n2)), e2.d = An(e2);
}
function An(e2) {
var t3 = e2.r, e2 = e2.l;
return (t3 ? e2 ? Math.max(t3.d, e2.d) : t3.d : e2 ? e2.d : 0) + 1;
}
function Cn(t3, n2) {
return O(n2).forEach(function(e2) {
t3[e2] ? Pn(t3[e2], n2[e2]) : t3[e2] = (function e3(t4) {
var n3, r2, o2 = {};
for (n3 in t4) m(t4, n3) && (r2 = t4[n3], o2[n3] = !r2 || "object" != typeof r2 || J.has(r2.constructor) ? r2 : e3(r2));
return o2;
})(n2[e2]);
}), t3;
}
function jn(t3, n2) {
return t3.all || n2.all || Object.keys(t3).some(function(e2) {
return n2[e2] && Kn(n2[e2], t3[e2]);
});
}
M(q.prototype, ((t2 = { add: function(e2) {
return Pn(this, e2), this;
}, addKey: function(e2) {
return On(this, e2, e2), this;
}, addKeys: function(e2) {
var t3 = this;
return e2.forEach(function(e3) {
return On(t3, e3, e3);
}), this;
}, hasKey: function(e2) {
var t3 = En(this).next(e2).value;
return t3 && C(t3.from, e2) <= 0 && 0 <= C(t3.to, e2);
} })[re] = function() {
return En(this);
}, t2));
var Tn = {}, In = {}, qn = false;
function Dn(e2) {
Cn(In, e2), qn || (qn = true, setTimeout(function() {
qn = false, Bn(In, !(In = {}));
}, 0));
}
function Bn(e2, t3) {
void 0 === t3 && (t3 = false);
var n2 = new Set();
if (e2.all) for (var r2 = 0, o2 = Object.values(Tn); r2 < o2.length; r2++) Rn(u2 = o2[r2], e2, n2, t3);
else for (var i2 in e2) {
var a2, u2, i2 = /^idb\:\/\/(.*)\/(.*)\//.exec(i2);
i2 && (a2 = i2[1], i2 = i2[2], u2 = Tn["idb://".concat(a2, "/").concat(i2)]) && Rn(u2, e2, n2, t3);
}
n2.forEach(function(e3) {
return e3();
});
}
function Rn(e2, t3, n2, r2) {
for (var o2 = [], i2 = 0, a2 = Object.entries(e2.queries.query); i2 < a2.length; i2++) {
for (var u2 = a2[i2], s2 = u2[0], c2 = [], l2 = 0, f2 = u2[1]; l2 < f2.length; l2++) {
var h2 = f2[l2];
jn(t3, h2.obsSet) ? h2.subscribers.forEach(function(e3) {
return n2.add(e3);
}) : r2 && c2.push(h2);
}
r2 && o2.push([s2, c2]);
}
if (r2) for (var d2 = 0, p2 = o2; d2 < p2.length; d2++) {
var y2 = p2[d2], s2 = y2[0], c2 = y2[1];
e2.queries.query[s2] = c2;
}
}
function Fn(h2) {
var d2 = h2._state, r2 = h2._deps.indexedDB;
if (d2.isBeingOpened || h2.idbdb) return d2.dbReadyPromise.then(function() {
return d2.dbOpenError ? S(d2.dbOpenError) : h2;
});
d2.isBeingOpened = true, d2.dbOpenError = null, d2.openComplete = false;
var t3 = d2.openCanceller, p2 = Math.round(10 * h2.verno), y2 = false;
function e2() {
if (d2.openCanceller !== t3) throw new k.DatabaseClosed("db.open() was cancelled");
}
function v2() {
return new K(function(c2, n3) {
if (e2(), !r2) throw new k.MissingAPI();
var l2 = h2.name, f2 = d2.autoSchema || !p2 ? r2.open(l2) : r2.open(l2, p2);
if (!f2) throw new k.MissingAPI();
f2.onerror = I(n3), f2.onblocked = E(h2._fireOnBlocked), f2.onupgradeneeded = E(function(e3) {
var t4;
m2 = f2.transaction, d2.autoSchema && !h2._options.allowEmptyDB ? (f2.onerror = Ut, m2.abort(), f2.result.close(), (t4 = r2.deleteDatabase(l2)).onsuccess = t4.onerror = E(function() {
n3(new k.NoSuchDatabase("Database ".concat(l2, " doesnt exist")));
})) : (m2.onerror = I(n3), t4 = e3.oldVersion > Math.pow(2, 62) ? 0 : e3.oldVersion, b2 = t4 < 1, h2.idbdb = f2.result, y2 && cn(h2, m2), sn(h2, t4 / 10, m2, n3));
}, n3), f2.onsuccess = E(function() {
m2 = null;
var e3, t4, n4, r3, o3, i2, a2 = h2.idbdb = f2.result, u2 = W(a2.objectStoreNames);
if (0 < u2.length) try {
var s2 = a2.transaction(1 === (o3 = u2).length ? o3[0] : o3, "readonly");
if (d2.autoSchema) i2 = a2, r3 = s2, (n4 = h2).verno = i2.version / 10, r3 = n4._dbSchema = pn(0, i2, r3), n4._storeNames = W(i2.objectStoreNames, 0), on(n4, [n4._allTables], O(r3), r3);
else if (yn(h2, h2._dbSchema, s2), t4 = s2, ((t4 = ln(pn(0, (e3 = h2).idbdb, t4), e3._dbSchema)).add.length || t4.change.some(function(e4) {
return e4.add.length || e4.change.length;
})) && !y2) return console.warn("Dexie SchemaDiff: Schema was extended without increasing the number passed to db.version(). Dexie will add missing parts and increment native version number to workaround this."), a2.close(), p2 = a2.version + 1, y2 = true, c2(v2());
rn(h2, s2);
} catch (e4) {
}
gn.add(h2), a2.onversionchange = E(function(e4) {
d2.vcFired = true, h2.on("versionchange").fire(e4);
}), a2.onclose = E(function() {
h2.close({ disableAutoOpen: false });
}), b2 && (u2 = h2._deps, o3 = l2, _n(i2 = u2.indexedDB) || o3 === ft || wn(i2, u2.IDBKeyRange).put({ name: o3 }).catch(g)), c2();
}, n3);
}).catch(function(e3) {
switch (null == e3 ? void 0 : e3.name) {
case "UnknownError":
if (0 < d2.PR1398_maxLoop) return d2.PR1398_maxLoop--, console.warn("Dexie: Workaround for Chrome UnknownError on open()"), v2();
break;
case "VersionError":
if (0 < p2) return p2 = 0, v2();
}
return K.reject(e3);
});
}
var n2, o2 = d2.dbReadyResolve, m2 = null, b2 = false;
return K.race([t3, ("undefined" == typeof navigator ? K.resolve() : !navigator.userAgentData && /Safari\//.test(navigator.userAgent) && !/Chrom(e|ium)\//.test(navigator.userAgent) && indexedDB.databases ? new Promise(function(e3) {
function t4() {
return indexedDB.databases().finally(e3);
}
n2 = setInterval(t4, 100), t4();
}).finally(function() {
return clearInterval(n2);
}) : Promise.resolve()).then(v2)]).then(function() {
return e2(), d2.onReadyBeingFired = [], K.resolve(xn(function() {
return h2.on.ready.fire(h2.vip);
})).then(function e3() {
var t4;
if (0 < d2.onReadyBeingFired.length) return t4 = d2.onReadyBeingFired.reduce(ke, g), d2.onReadyBeingFired = [], K.resolve(xn(function() {
return t4(h2.vip);
})).then(e3);
});
}).finally(function() {
d2.openCanceller === t3 && (d2.onReadyBeingFired = null, d2.isBeingOpened = false);
}).catch(function(e3) {
d2.dbOpenError = e3;
try {
m2 && m2.abort();
} catch (e4) {
}
return t3 === d2.openCanceller && h2._close(), S(e3);
}).finally(function() {
d2.openComplete = true, o2();
}).then(function() {
var n3;
return b2 && (n3 = {}, h2.tables.forEach(function(t4) {
t4.schema.indexes.forEach(function(e3) {
e3.name && (n3["idb://".concat(h2.name, "/").concat(t4.name, "/").concat(e3.name)] = new q(-1 / 0, [[[]]]));
}), n3["idb://".concat(h2.name, "/").concat(t4.name, "/")] = n3["idb://".concat(h2.name, "/").concat(t4.name, "/:dels")] = new q(-1 / 0, [[[]]]);
}), Wt(zt).fire(n3), Bn(n3, true)), h2;
});
}
function Nn(t3) {
function e2(e3) {
return t3.next(e3);
}
var r2 = n2(e2), o2 = n2(function(e3) {
return t3.throw(e3);
});
function n2(n3) {
return function(e3) {
var e3 = n3(e3), t4 = e3.value;
return e3.done ? t4 : t4 && "function" == typeof t4.then ? t4.then(r2, o2) : x(t4) ? Promise.all(t4).then(r2, o2) : r2(t4);
};
}
return n2(e2)();
}
function Mn(e2, t3, n2) {
for (var r2 = x(e2) ? e2.slice() : [e2], o2 = 0; o2 < n2; ++o2) r2.push(t3);
return r2;
}
var Ln = { stack: "dbcore", name: "VirtualIndexMiddleware", level: 1, create: function(l2) {
return _(_({}, l2), { table: function(e2) {
var i2 = l2.table(e2), e2 = i2.schema, u2 = {}, s2 = [];
function c2(e3, t4, n3) {
var r3 = en(e3), o3 = u2[r3] = u2[r3] || [], i3 = null == e3 ? 0 : "string" == typeof e3 ? 1 : e3.length, a3 = 0 < t4, r3 = _(_({}, n3), { name: a3 ? "".concat(r3, "(virtual-from:").concat(n3.name, ")") : n3.name, lowLevelIndex: n3, isVirtual: a3, keyTail: t4, keyLength: i3, extractKey: Ht(e3), unique: !a3 && n3.unique });
return o3.push(r3), r3.isPrimaryKey || s2.push(r3), 1 < i3 && c2(2 === i3 ? e3[0] : e3.slice(0, i3 - 1), t4 + 1, n3), o3.sort(function(e4, t5) {
return e4.keyTail - t5.keyTail;
}), r3;
}
var t3 = c2(e2.primaryKey.keyPath, 0, e2.primaryKey);
u2[":id"] = [t3];
for (var n2 = 0, r2 = e2.indexes; n2 < r2.length; n2++) {
var o2 = r2[n2];
c2(o2.keyPath, 0, o2);
}
function a2(e3) {
var t4, n3 = e3.query.index;
return n3.isVirtual ? _(_({}, e3), { query: { index: n3.lowLevelIndex, range: (t4 = e3.query.range, n3 = n3.keyTail, { type: 1 === t4.type ? 2 : t4.type, lower: Mn(t4.lower, t4.lowerOpen ? l2.MAX_KEY : l2.MIN_KEY, n3), lowerOpen: true, upper: Mn(t4.upper, t4.upperOpen ? l2.MIN_KEY : l2.MAX_KEY, n3), upperOpen: true }) } }) : e3;
}
return _(_({}, i2), { schema: _(_({}, e2), { primaryKey: t3, indexes: s2, getIndexByKeyPath: function(e3) {
return (e3 = u2[en(e3)]) && e3[0];
} }), count: function(e3) {
return i2.count(a2(e3));
}, query: function(e3) {
return i2.query(a2(e3));
}, openCursor: function(t4) {
var e3 = t4.query.index, r3 = e3.keyTail, o3 = e3.keyLength;
return e3.isVirtual ? i2.openCursor(a2(t4)).then(function(e4) {
return e4 && n3(e4);
}) : i2.openCursor(t4);
function n3(n4) {
return Object.create(n4, { continue: { value: function(e4) {
null != e4 ? n4.continue(Mn(e4, t4.reverse ? l2.MAX_KEY : l2.MIN_KEY, r3)) : t4.unique ? n4.continue(n4.key.slice(0, o3).concat(t4.reverse ? l2.MIN_KEY : l2.MAX_KEY, r3)) : n4.continue();
} }, continuePrimaryKey: { value: function(e4, t5) {
n4.continuePrimaryKey(Mn(e4, l2.MAX_KEY, r3), t5);
} }, primaryKey: { get: function() {
return n4.primaryKey;
} }, key: { get: function() {
var e4 = n4.key;
return 1 === o3 ? e4[0] : e4.slice(0, o3);
} }, value: { get: function() {
return n4.value;
} } });
}
} });
} });
} };
function Un(o2, i2, a2, u2) {
return a2 = a2 || {}, u2 = u2 || "", O(o2).forEach(function(e2) {
var t3, n2, r2;
m(i2, e2) ? (t3 = o2[e2], n2 = i2[e2], "object" == typeof t3 && "object" == typeof n2 && t3 && n2 ? (r2 = ne(t3)) !== ne(n2) ? a2[u2 + e2] = i2[e2] : "Object" === r2 ? Un(t3, n2, a2, u2 + e2 + ".") : t3 !== n2 && (a2[u2 + e2] = i2[e2]) : t3 !== n2 && (a2[u2 + e2] = i2[e2])) : a2[u2 + e2] = void 0;
}), O(i2).forEach(function(e2) {
m(o2, e2) || (a2[u2 + e2] = i2[e2]);
}), a2;
}
function zn(e2, t3) {
return "delete" === t3.type ? t3.keys : t3.keys || t3.values.map(e2.extractKey);
}
var Vn = { stack: "dbcore", name: "HooksMiddleware", level: 2, create: function(e2) {
return _(_({}, e2), { table: function(r2) {
var y2 = e2.table(r2), v2 = y2.schema.primaryKey;
return _(_({}, y2), { mutate: function(e3) {
var t3 = P.trans, n2 = t3.table(r2).hook, h2 = n2.deleting, d2 = n2.creating, p2 = n2.updating;
switch (e3.type) {
case "add":
if (d2.fire === g) break;
return t3._promise("readwrite", function() {
return a2(e3);
}, true);
case "put":
if (d2.fire === g && p2.fire === g) break;
return t3._promise("readwrite", function() {
return a2(e3);
}, true);
case "delete":
if (h2.fire === g) break;
return t3._promise("readwrite", function() {
return a2(e3);
}, true);
case "deleteRange":
if (h2.fire === g) break;
return t3._promise("readwrite", function() {
return (function n3(r3, o2, i2) {
return y2.query({ trans: r3, values: false, query: { index: v2, range: o2 }, limit: i2 }).then(function(e4) {
var t4 = e4.result;
return a2({ type: "delete", keys: t4, trans: r3 }).then(function(e5) {
return 0 < e5.numFailures ? Promise.reject(e5.failures[0]) : t4.length < i2 ? { failures: [], numFailures: 0, lastResult: void 0 } : n3(r3, _(_({}, o2), { lower: t4[t4.length - 1], lowerOpen: true }), i2);
});
});
})(e3.trans, e3.range, 1e4);
}, true);
}
return y2.mutate(e3);
function a2(c2) {
var e4, t4, n3, l2 = P.trans, f2 = c2.keys || zn(v2, c2);
if (f2) return "delete" !== (c2 = "add" === c2.type || "put" === c2.type ? _(_({}, c2), { keys: f2 }) : _({}, c2)).type && (c2.values = R([], c2.values)), c2.keys && (c2.keys = R([], c2.keys)), e4 = y2, n3 = f2, ("add" === (t4 = c2).type ? Promise.resolve([]) : e4.getMany({ trans: t4.trans, keys: n3, cache: "immutable" })).then(function(u2) {
var s2 = f2.map(function(e5, t5) {
var n4, r3, o2, i2 = u2[t5], a3 = { onerror: null, onsuccess: null };
return "delete" === c2.type ? h2.fire.call(a3, e5, i2, l2) : "add" === c2.type || void 0 === i2 ? (n4 = d2.fire.call(a3, e5, c2.values[t5], l2), null == e5 && null != n4 && (c2.keys[t5] = e5 = n4, v2.outbound || b(c2.values[t5], v2.keyPath, e5))) : (n4 = Un(i2, c2.values[t5]), (r3 = p2.fire.call(a3, n4, e5, i2, l2)) && (o2 = c2.values[t5], Object.keys(r3).forEach(function(e6) {
m(o2, e6) ? o2[e6] = r3[e6] : b(o2, e6, r3[e6]);
}))), a3;
});
return y2.mutate(c2).then(function(e5) {
for (var t5 = e5.failures, n4 = e5.results, r3 = e5.numFailures, e5 = e5.lastResult, o2 = 0; o2 < f2.length; ++o2) {
var i2 = (n4 || f2)[o2], a3 = s2[o2];
null == i2 ? a3.onerror && a3.onerror(t5[o2]) : a3.onsuccess && a3.onsuccess("put" === c2.type && u2[o2] ? c2.values[o2] : i2);
}
return { failures: t5, results: n4, numFailures: r3, lastResult: e5 };
}).catch(function(t5) {
return s2.forEach(function(e5) {
return e5.onerror && e5.onerror(t5);
}), Promise.reject(t5);
});
});
throw new Error("Keys missing");
}
} });
} });
} };
function Wn(e2, t3, n2) {
try {
if (!t3) return null;
if (t3.keys.length < e2.length) return null;
for (var r2 = [], o2 = 0, i2 = 0; o2 < t3.keys.length && i2 < e2.length; ++o2) 0 === C(t3.keys[o2], e2[i2]) && (r2.push(n2 ? ee(t3.values[o2]) : t3.values[o2]), ++i2);
return r2.length === e2.length ? r2 : null;
} catch (e3) {
return null;
}
}
var Yn = { stack: "dbcore", level: -1, create: function(t3) {
return { table: function(e2) {
var n2 = t3.table(e2);
return _(_({}, n2), { getMany: function(t4) {
var e3;
return t4.cache ? (e3 = Wn(t4.keys, t4.trans._cache, "clone" === t4.cache)) ? K.resolve(e3) : n2.getMany(t4).then(function(e4) {
return t4.trans._cache = { keys: t4.keys, values: "clone" === t4.cache ? ee(e4) : e4 }, e4;
}) : n2.getMany(t4);
}, mutate: function(e3) {
return "add" !== e3.type && (e3.trans._cache = null), n2.mutate(e3);
} });
} };
} };
function $n(e2, t3) {
return "readonly" === e2.trans.mode && !!e2.subscr && !e2.trans.explicit && "disabled" !== e2.trans.db._options.cache && !t3.schema.primaryKey.outbound;
}
function Qn(e2, t3) {
switch (e2) {
case "query":
return t3.values && !t3.unique;
case "get":
case "getMany":
case "count":
case "openCursor":
return false;
}
}
var Gn = { stack: "dbcore", level: 0, name: "Observability", create: function(b2) {
var g2 = b2.schema.name, w2 = new q(b2.MIN_KEY, b2.MAX_KEY);
return _(_({}, b2), { transaction: function(e2, t3, n2) {
if (P.subscr && "readonly" !== t3) throw new k.ReadOnly("Readwrite transaction in liveQuery context. Querier source: ".concat(P.querier));
return b2.transaction(e2, t3, n2);
}, table: function(d2) {
function e2(e3) {
var t4, e3 = e3.query;
return [t4 = e3.index, new q(null != (t4 = (e3 = e3.range).lower) ? t4 : b2.MIN_KEY, null != (t4 = e3.upper) ? t4 : b2.MAX_KEY)];
}
var p2 = b2.table(d2), y2 = p2.schema, v2 = y2.primaryKey, t3 = y2.indexes, c2 = v2.extractKey, l2 = v2.outbound, m2 = v2.autoIncrement && t3.filter(function(e3) {
return e3.compound && e3.keyPath.includes(v2.keyPath);
}), n2 = _(_({}, p2), { mutate: function(a2) {
function u2(e4) {
return e4 = "idb://".concat(g2, "/").concat(d2, "/").concat(e4), n3[e4] || (n3[e4] = new q());
}
var e3, i2, s2, t4 = a2.trans, n3 = a2.mutatedParts || (a2.mutatedParts = {}), r2 = u2(""), o2 = u2(":dels"), c3 = a2.type, l3 = "deleteRange" === a2.type ? [a2.range] : "delete" === a2.type ? [a2.keys] : a2.values.length < 50 ? [zn(v2, a2).filter(function(e4) {
return e4;
}), a2.values] : [], f3 = l3[0], l3 = l3[1], h2 = a2.trans._cache;
return x(f3) ? (r2.addKeys(f3), (c3 = "delete" === c3 || f3.length === l3.length ? Wn(f3, h2) : null) || o2.addKeys(f3), (c3 || l3) && (e3 = u2, i2 = c3, s2 = l3, y2.indexes.forEach(function(t5) {
var n4 = e3(t5.name || "");
function r3(e4) {
return null != e4 ? t5.extractKey(e4) : null;
}
function o3(e4) {
t5.multiEntry && x(e4) ? e4.forEach(function(e5) {
return n4.addKey(e5);
}) : n4.addKey(e4);
}
(i2 || s2).forEach(function(e4, t6) {
var n5 = i2 && r3(i2[t6]), t6 = s2 && r3(s2[t6]);
0 !== C(n5, t6) && (null != n5 && o3(n5), null != t6) && o3(t6);
});
}))) : f3 ? (l3 = { from: null != (h2 = f3.lower) ? h2 : b2.MIN_KEY, to: null != (c3 = f3.upper) ? c3 : b2.MAX_KEY }, o2.add(l3), r2.add(l3)) : (r2.add(w2), o2.add(w2), y2.indexes.forEach(function(e4) {
return u2(e4.name).add(w2);
})), p2.mutate(a2).then(function(i3) {
return !f3 || "add" !== a2.type && "put" !== a2.type || (r2.addKeys(i3.results), m2 && m2.forEach(function(t5) {
for (var e4 = a2.values.map(function(e5) {
return t5.extractKey(e5);
}), n4 = t5.keyPath.findIndex(function(e5) {
return e5 === v2.keyPath;
}), r3 = 0, o3 = i3.results.length; r3 < o3; ++r3) e4[r3][n4] = i3.results[r3];
u2(t5.name).addKeys(e4);
})), t4.mutatedParts = Cn(t4.mutatedParts || {}, n3), i3;
});
} }), f2 = { get: function(e3) {
return [v2, new q(e3.key)];
}, getMany: function(e3) {
return [v2, new q().addKeys(e3.keys)];
}, count: e2, query: e2, openCursor: e2 };
return O(f2).forEach(function(s2) {
n2[s2] = function(o2) {
var e3 = P.subscr, t4 = !!e3, n3 = $n(P, p2) && Qn(s2, o2) ? o2.obsSet = {} : e3;
if (t4) {
var i2, e3 = function(e4) {
e4 = "idb://".concat(g2, "/").concat(d2, "/").concat(e4);
return n3[e4] || (n3[e4] = new q());
}, a2 = e3(""), u2 = e3(":dels"), t4 = f2[s2](o2), r2 = t4[0], t4 = t4[1];
if (("query" === s2 && r2.isPrimaryKey && !o2.values ? u2 : e3(r2.name || "")).add(t4), !r2.isPrimaryKey) {
if ("count" !== s2) return i2 = "query" === s2 && l2 && o2.values && p2.query(_(_({}, o2), { values: false })), p2[s2].apply(this, arguments).then(function(t5) {
if ("query" === s2) {
if (l2 && o2.values) return i2.then(function(e5) {
e5 = e5.result;
return a2.addKeys(e5), t5;
});
var e4 = o2.values ? t5.result.map(c2) : t5.result;
(o2.values ? a2 : u2).addKeys(e4);
} else {
var n4, r3;
if ("openCursor" === s2) return r3 = o2.values, (n4 = t5) && Object.create(n4, { key: { get: function() {
return u2.addKey(n4.primaryKey), n4.key;
} }, primaryKey: { get: function() {
var e5 = n4.primaryKey;
return u2.addKey(e5), e5;
} }, value: { get: function() {
return r3 && a2.addKey(n4.primaryKey), n4.value;
} } });
}
return t5;
});
u2.add(w2);
}
}
return p2[s2].apply(this, arguments);
};
}), n2;
} });
} };
function Xn(e2, t3, n2) {
var r2;
return 0 === n2.numFailures ? t3 : "deleteRange" === t3.type || (r2 = t3.keys ? t3.keys.length : "values" in t3 && t3.values ? t3.values.length : 1, n2.numFailures === r2) ? null : (r2 = _({}, t3), x(r2.keys) && (r2.keys = r2.keys.filter(function(e3, t4) {
return !(t4 in n2.failures);
})), "values" in r2 && x(r2.values) && (r2.values = r2.values.filter(function(e3, t4) {
return !(t4 in n2.failures);
})), r2);
}
function Hn(e2, t3) {
return n2 = e2, (void 0 === (r2 = t3).lower || (r2.lowerOpen ? 0 < C(n2, r2.lower) : 0 <= C(n2, r2.lower))) && (n2 = e2, void 0 === (r2 = t3).upper || (r2.upperOpen ? C(n2, r2.upper) < 0 : C(n2, r2.upper) <= 0));
var n2, r2;
}
function Jn(e2, d2, t3, n2, r2, o2) {
var i2, p2, y2, v2, m2, a2, u2;
return !t3 || 0 === t3.length || (i2 = d2.query.index, p2 = i2.multiEntry, y2 = d2.query.range, v2 = n2.schema.primaryKey.extractKey, m2 = i2.extractKey, a2 = (i2.lowLevelIndex || i2).extractKey, (n2 = t3.reduce(function(e3, t4) {
var n3 = e3, r3 = [];
if ("add" === t4.type || "put" === t4.type) for (var o3 = new q(), i3 = t4.values.length - 1; 0 <= i3; --i3) {
var a3, u3 = t4.values[i3], s2 = v2(u3);
!o3.hasKey(s2) && (a3 = m2(u3), p2 && x(a3) ? a3.some(function(e4) {
return Hn(e4, y2);
}) : Hn(a3, y2)) && (o3.addKey(s2), r3.push(u3));
}
switch (t4.type) {
case "add":
var c2 = new q().addKeys(d2.values ? e3.map(function(e4) {
return v2(e4);
}) : e3), n3 = e3.concat(d2.values ? r3.filter(function(e4) {
e4 = v2(e4);
return !c2.hasKey(e4) && (c2.addKey(e4), true);
}) : r3.map(function(e4) {
return v2(e4);
}).filter(function(e4) {
return !c2.hasKey(e4) && (c2.addKey(e4), true);
}));
break;
case "put":
var l2 = new q().addKeys(t4.values.map(function(e4) {
return v2(e4);
}));
n3 = e3.filter(function(e4) {
return !l2.hasKey(d2.values ? v2(e4) : e4);
}).concat(d2.values ? r3 : r3.map(function(e4) {
return v2(e4);
}));
break;
case "delete":
var f2 = new q().addKeys(t4.keys);
n3 = e3.filter(function(e4) {
return !f2.hasKey(d2.values ? v2(e4) : e4);
});
break;
case "deleteRange":
var h2 = t4.range;
n3 = e3.filter(function(e4) {
return !Hn(v2(e4), h2);
});
}
return n3;
}, e2)) === e2) ? e2 : (u2 = function(e3, t4) {
return C(a2(e3), a2(t4)) || C(v2(e3), v2(t4));
}, n2.sort("prev" === d2.direction || "prevunique" === d2.direction ? function(e3, t4) {
return u2(t4, e3);
} : u2), d2.limit && d2.limit < 1 / 0 && (n2.length > d2.limit ? n2.length = d2.limit : e2.length === d2.limit && n2.length < d2.limit && (r2.dirty = true)), o2 ? Object.freeze(n2) : n2);
}
function Zn(e2, t3) {
return 0 === C(e2.lower, t3.lower) && 0 === C(e2.upper, t3.upper) && !!e2.lowerOpen == !!t3.lowerOpen && !!e2.upperOpen == !!t3.upperOpen;
}
function er(e2, t3) {
return ((e3, t4, n2, r2) => {
if (void 0 === e3) return void 0 !== t4 ? -1 : 0;
if (void 0 === t4) return 1;
if (0 === (e3 = C(e3, t4))) {
if (n2 && r2) return 0;
if (n2) return 1;
if (r2) return -1;
}
return e3;
})(e2.lower, t3.lower, e2.lowerOpen, t3.lowerOpen) <= 0 && 0 <= ((e3, t4, n2, r2) => {
if (void 0 === e3) return void 0 !== t4 ? 1 : 0;
if (void 0 === t4) return -1;
if (0 === (e3 = C(e3, t4))) {
if (n2 && r2) return 0;
if (n2) return -1;
if (r2) return 1;
}
return e3;
})(e2.upper, t3.upper, e2.upperOpen, t3.upperOpen);
}
function tr(n2, r2, o2, e2) {
n2.subscribers.add(o2), e2.addEventListener("abort", function() {
var e3, t3;
n2.subscribers.delete(o2), 0 === n2.subscribers.size && (e3 = n2, t3 = r2, setTimeout(function() {
0 === e3.subscribers.size && ie(t3, e3);
}, 3e3));
});
}
var nr = { stack: "dbcore", level: 0, name: "Cache", create: function(k2) {
var O2 = k2.schema.name;
return _(_({}, k2), { transaction: function(g2, w2, e2) {
var _2, t3, x2 = k2.transaction(g2, w2, e2);
return "readwrite" === w2 && (e2 = (_2 = new AbortController()).signal, x2.addEventListener("abort", (t3 = function(b2) {
return function() {
if (_2.abort(), "readwrite" === w2) {
for (var t4 = new Set(), e3 = 0, n2 = g2; e3 < n2.length; e3++) {
var r2 = n2[e3], o2 = Tn["idb://".concat(O2, "/").concat(r2)];
if (o2) {
var i2 = k2.table(r2), a2 = o2.optimisticOps.filter(function(e4) {
return e4.trans === x2;
});
if (x2._explicit && b2 && x2.mutatedParts) for (var u2 = 0, s2 = Object.values(o2.queries.query); u2 < s2.length; u2++) for (var c2 = 0, l2 = (d2 = s2[u2]).slice(); c2 < l2.length; c2++) jn((p2 = l2[c2]).obsSet, x2.mutatedParts) && (ie(d2, p2), p2.subscribers.forEach(function(e4) {
return t4.add(e4);
}));
else if (0 < a2.length) {
o2.optimisticOps = o2.optimisticOps.filter(function(e4) {
return e4.trans !== x2;
});
for (var f2 = 0, h2 = Object.values(o2.queries.query); f2 < h2.length; f2++) for (var d2, p2, y2, v2 = 0, m2 = (d2 = h2[f2]).slice(); v2 < m2.length; v2++) null != (p2 = m2[v2]).res && x2.mutatedParts && (b2 && !p2.dirty ? (y2 = Object.isFrozen(p2.res), y2 = Jn(p2.res, p2.req, a2, i2, p2, y2), p2.dirty ? (ie(d2, p2), p2.subscribers.forEach(function(e4) {
return t4.add(e4);
})) : y2 !== p2.res && (p2.res = y2, p2.promise = K.resolve({ result: y2 }))) : (p2.dirty && ie(d2, p2), p2.subscribers.forEach(function(e4) {
return t4.add(e4);
})));
}
}
}
t4.forEach(function(e4) {
return e4();
});
}
};
})(false), { signal: e2 }), x2.addEventListener("error", t3(false), { signal: e2 }), x2.addEventListener("complete", t3(true), { signal: e2 })), x2;
}, table: function(s2) {
var c2 = k2.table(s2), o2 = c2.schema.primaryKey;
return _(_({}, c2), { mutate: function(t3) {
var n2, e2 = P.trans;
return !o2.outbound && "disabled" !== e2.db._options.cache && !e2.explicit && "readwrite" === e2.idbtrans.mode && (n2 = Tn["idb://".concat(O2, "/").concat(s2)]) ? (e2 = c2.mutate(t3), "add" !== t3.type && "put" !== t3.type || !(50 <= t3.values.length || zn(o2, t3).some(function(e3) {
return null == e3;
})) ? (n2.optimisticOps.push(t3), t3.mutatedParts && Dn(t3.mutatedParts), e2.then(function(e3) {
0 < e3.numFailures && (ie(n2.optimisticOps, t3), (e3 = Xn(0, t3, e3)) && n2.optimisticOps.push(e3), t3.mutatedParts) && Dn(t3.mutatedParts);
}), e2.catch(function() {
ie(n2.optimisticOps, t3), t3.mutatedParts && Dn(t3.mutatedParts);
})) : e2.then(function(r2) {
var e3 = Xn(0, _(_({}, t3), { values: t3.values.map(function(e4, t4) {
var n3;
return r2.failures[t4] ? e4 : (b(n3 = null != (n3 = o2.keyPath) && n3.includes(".") ? ee(e4) : _({}, e4), o2.keyPath, r2.results[t4]), n3);
}) }), r2);
n2.optimisticOps.push(e3), queueMicrotask(function() {
return t3.mutatedParts && Dn(t3.mutatedParts);
});
}), e2) : c2.mutate(t3);
}, query: function(t3) {
var o3, e2, n2, r2, i2, a2, u2;
return $n(P, c2) && Qn("query", t3) ? (o3 = "immutable" === (null == (n2 = P.trans) ? void 0 : n2.db._options.cache), e2 = (n2 = P).requery, n2 = n2.signal, a2 = ((e3, t4, n3, r3) => {
var o4 = Tn["idb://".concat(e3, "/").concat(t4)];
if (!o4) return [];
if (!(e3 = o4.queries[n3])) return [null, false, o4, null];
var i3 = e3[(r3.query ? r3.query.index.name : null) || ""];
if (!i3) return [null, false, o4, null];
switch (n3) {
case "query":
var a3 = null != (u3 = r3.direction) ? u3 : "next", u3 = i3.find(function(e4) {
var t5;
return e4.req.limit === r3.limit && e4.req.values === r3.values && (null != (t5 = e4.req.direction) ? t5 : "next") === a3 && Zn(e4.req.query.range, r3.query.range);
});
return u3 ? [u3, true, o4, i3] : [i3.find(function(e4) {
var t5;
return ("limit" in e4.req ? e4.req.limit : 1 / 0) >= r3.limit && (null != (t5 = e4.req.direction) ? t5 : "next") === a3 && (!r3.values || e4.req.values) && er(e4.req.query.range, r3.query.range);
}), false, o4, i3];
case "count":
u3 = i3.find(function(e4) {
return Zn(e4.req.query.range, r3.query.range);
});
return [u3, !!u3, o4, i3];
}
})(O2, s2, "query", t3), u2 = a2[0], r2 = a2[2], i2 = a2[3], u2 && a2[1] ? u2.obsSet = t3.obsSet : (a2 = c2.query(t3).then(function(e3) {
var t4 = e3.result;
if (u2 && (u2.res = t4), o3) {
for (var n3 = 0, r3 = t4.length; n3 < r3; ++n3) Object.freeze(t4[n3]);
Object.freeze(t4);
} else e3.result = ee(t4);
return e3;
}).catch(function(e3) {
return i2 && u2 && ie(i2, u2), Promise.reject(e3);
}), u2 = { obsSet: t3.obsSet, promise: a2, subscribers: new Set(), type: "query", req: t3, dirty: false }, i2 ? i2.push(u2) : (i2 = [u2], (r2 = r2 || (Tn["idb://".concat(O2, "/").concat(s2)] = { queries: { query: {}, count: {} }, objs: new Map(), optimisticOps: [], unsignaledParts: {} })).queries.query[t3.query.index.name || ""] = i2)), tr(u2, i2, e2, n2), u2.promise.then(function(e3) {
return { result: Jn(e3.result, t3, null == r2 ? void 0 : r2.optimisticOps, c2, u2, o3) };
})) : c2.query(t3);
} });
} });
} };
function rr(e2, r2) {
return new Proxy(e2, { get: function(e3, t3, n2) {
return "db" === t3 ? r2 : Reflect.get(e3, t3, n2);
} });
}
D.prototype.version = function(t3) {
if (isNaN(t3) || t3 < 0.1) throw new k.Type("Given version is not a positive number");
if (t3 = Math.round(10 * t3) / 10, this.idbdb || this._state.isBeingOpened) throw new k.Schema("Cannot add version when database is open");
this.verno = Math.max(this.verno, t3);
var e2 = this._versions, n2 = e2.filter(function(e3) {
return e3._cfg.version === t3;
})[0];
return n2 || (n2 = new this.Version(t3), e2.push(n2), e2.sort(un), n2.stores({}), this._state.autoSchema = false), n2;
}, D.prototype._whenReady = function(e2) {
var n2 = this;
return this.idbdb && (this._state.openComplete || P.letThrough || this._vip) ? e2() : new K(function(e3, t3) {
if (n2._state.openComplete) return t3(new k.DatabaseClosed(n2._state.dbOpenError));
if (!n2._state.isBeingOpened) {
if (!n2._state.autoOpen) return void t3(new k.DatabaseClosed());
n2.open().catch(g);
}
n2._state.dbReadyPromise.then(e3, t3);
}).then(e2);
}, D.prototype.use = function(e2) {
var t3 = e2.stack, n2 = e2.create, r2 = e2.level, e2 = e2.name, o2 = (e2 && this.unuse({ stack: t3, name: e2 }), this._middlewares[t3] || (this._middlewares[t3] = []));
return o2.push({ stack: t3, create: n2, level: null == r2 ? 10 : r2, name: e2 }), o2.sort(function(e3, t4) {
return e3.level - t4.level;
}), this;
}, D.prototype.unuse = function(e2) {
var t3 = e2.stack, n2 = e2.name, r2 = e2.create;
return t3 && this._middlewares[t3] && (this._middlewares[t3] = this._middlewares[t3].filter(function(e3) {
return r2 ? e3.create !== r2 : !!n2 && e3.name !== n2;
})), this;
}, D.prototype.open = function() {
var e2 = this;
return at(s, function() {
return Fn(e2);
});
}, D.prototype._close = function() {
this.on.close.fire(new CustomEvent("close"));
var n2 = this._state;
if (gn.remove(this), this.idbdb) {
try {
this.idbdb.close();
} catch (e2) {
}
this.idbdb = null;
}
n2.isBeingOpened || (n2.dbReadyPromise = new K(function(e2) {
n2.dbReadyResolve = e2;
}), n2.openCanceller = new K(function(e2, t3) {
n2.cancelOpen = t3;
}));
}, D.prototype.close = function(e2) {
var e2 = (void 0 === e2 ? { disableAutoOpen: true } : e2).disableAutoOpen, t3 = this._state;
e2 ? (t3.isBeingOpened && t3.cancelOpen(new k.DatabaseClosed()), this._close(), t3.autoOpen = false, t3.dbOpenError = new k.DatabaseClosed()) : (this._close(), t3.autoOpen = this._options.autoOpen || t3.isBeingOpened, t3.openComplete = false, t3.dbOpenError = null);
}, D.prototype.delete = function(n2) {
var o2 = this, i2 = (void 0 === n2 && (n2 = { disableAutoOpen: true }), 0 < arguments.length && "object" != typeof arguments[0]), a2 = this._state;
return new K(function(r2, t3) {
function e2() {
o2.close(n2);
var e3 = o2._deps.indexedDB.deleteDatabase(o2.name);
e3.onsuccess = E(function() {
var e4, t4, n3;
e4 = o2._deps, t4 = o2.name, _n(n3 = e4.indexedDB) || t4 === ft || wn(n3, e4.IDBKeyRange).delete(t4).catch(g), r2();
}), e3.onerror = I(t3), e3.onblocked = o2._fireOnBlocked;
}
if (i2) throw new k.InvalidArgument("Invalid closeOptions argument to db.delete()");
a2.isBeingOpened ? a2.dbReadyPromise.then(e2) : e2();
});
}, D.prototype.backendDB = function() {
return this.idbdb;
}, D.prototype.isOpen = function() {
return null !== this.idbdb;
}, D.prototype.hasBeenClosed = function() {
var e2 = this._state.dbOpenError;
return e2 && "DatabaseClosed" === e2.name;
}, D.prototype.hasFailed = function() {
return null !== this._state.dbOpenError;
}, D.prototype.dynamicallyOpened = function() {
return this._state.autoSchema;
}, Object.defineProperty(D.prototype, "tables", { get: function() {
var t3 = this;
return O(this._allTables).map(function(e2) {
return t3._allTables[e2];
});
}, enumerable: false, configurable: true }), D.prototype.transaction = function() {
var e2 = (function(e3, t3, n2) {
var r2 = arguments.length;
if (r2 < 2) throw new k.InvalidArgument("Too few arguments");
for (var o2 = new Array(r2 - 1); --r2; ) o2[r2 - 1] = arguments[r2];
return n2 = o2.pop(), [e3, H(o2), n2];
}).apply(this, arguments);
return this._transaction.apply(this, e2);
}, D.prototype._transaction = function(e2, t3, n2) {
var r2, o2, i2 = this, a2 = P.trans, u2 = (a2 && a2.db === this && -1 === e2.indexOf("!") || (a2 = null), -1 !== e2.indexOf("?"));
e2 = e2.replace("!", "").replace("?", "");
try {
if (o2 = t3.map(function(e3) {
e3 = e3 instanceof i2.Table ? e3.name : e3;
if ("string" != typeof e3) throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed");
return e3;
}), "r" == e2 || e2 === ht) r2 = ht;
else {
if ("rw" != e2 && e2 != dt) throw new k.InvalidArgument("Invalid transaction mode: " + e2);
r2 = dt;
}
if (a2) {
if (a2.mode === ht && r2 === dt) {
if (!u2) throw new k.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY");
a2 = null;
}
a2 && o2.forEach(function(e3) {
if (a2 && -1 === a2.storeNames.indexOf(e3)) {
if (!u2) throw new k.SubTransaction("Table " + e3 + " not included in parent transaction.");
a2 = null;
}
}), u2 && a2 && !a2.active && (a2 = null);
}
} catch (n3) {
return a2 ? a2._promise(null, function(e3, t4) {
t4(n3);
}) : S(n3);
}
var s2 = (function o3(i3, a3, u3, s3, c2) {
return K.resolve().then(function() {
var e3 = P.transless || P, t4 = i3._createTransaction(a3, u3, i3._dbSchema, s3), e3 = (t4.explicit = true, { trans: t4, transless: e3 });
if (s3) t4.idbtrans = s3.idbtrans;
else try {
t4.create(), t4.idbtrans._explicit = true, i3._state.PR1398_maxLoop = 3;
} catch (e4) {
return e4.name === de.InvalidState && i3.isOpen() && 0 < --i3._state.PR1398_maxLoop ? (console.warn("Dexie: Need to reopen db"), i3.close({ disableAutoOpen: false }), i3.open().then(function() {
return o3(i3, a3, u3, null, c2);
})) : S(e4);
}
var n3, r3 = ue(c2), e3 = (r3 && nt(), K.follow(function() {
var e4;
(n3 = c2.call(t4, t4)) && (r3 ? (e4 = w.bind(null, null), n3.then(e4, e4)) : "function" == typeof n3.next && "function" == typeof n3.throw && (n3 = Nn(n3)));
}, e3));
return (n3 && "function" == typeof n3.then ? K.resolve(n3).then(function(e4) {
return t4.active ? e4 : S(new k.PrematureCommit("Transaction committed too early. See http://bit.ly/2kdckMn"));
}) : e3.then(function() {
return n3;
})).then(function(e4) {
return s3 && t4._resolve(), t4._completion.then(function() {
return e4;
});
}).catch(function(e4) {
return t4._reject(e4), S(e4);
});
});
}).bind(null, this, r2, o2, a2, n2);
return a2 ? a2._promise(r2, s2, "lock") : P.trans ? at(P.transless, function() {
return i2._whenReady(s2);
}) : this._whenReady(s2);
}, D.prototype.table = function(e2) {
if (m(this._allTables, e2)) return this._allTables[e2];
throw new k.InvalidTable("Table ".concat(e2, " does not exist"));
};
var y = D;
function D(e2, t3) {
var i2, r2, a2, n2, o2, u2 = this, s2 = (this._middlewares = {}, this.verno = 0, D.dependencies), s2 = (this._options = t3 = _({ addons: D.addons, autoOpen: true, indexedDB: s2.indexedDB, IDBKeyRange: s2.IDBKeyRange, cache: "cloned", maxConnections: 1e3 }, t3), this._deps = { indexedDB: t3.indexedDB, IDBKeyRange: t3.IDBKeyRange }, t3.addons), c2 = (this._dbSchema = {}, this._versions = [], this._storeNames = [], this._allTables = {}, this.idbdb = null, this._novip = this, { dbOpenError: null, isBeingOpened: false, onReadyBeingFired: null, openComplete: false, dbReadyResolve: g, dbReadyPromise: null, cancelOpen: g, openCanceller: null, autoSchema: true, PR1398_maxLoop: 3, autoOpen: t3.autoOpen }), l2 = (c2.dbReadyPromise = new K(function(e3) {
c2.dbReadyResolve = e3;
}), c2.openCanceller = new K(function(e3, t4) {
c2.cancelOpen = t4;
}), this._state = c2, this.name = e2, this.on = Pt(this, "populate", "blocked", "versionchange", "close", { ready: [ke, g] }), this.once = function(n3, r3) {
var o3 = function() {
for (var e3 = [], t4 = 0; t4 < arguments.length; t4++) e3[t4] = arguments[t4];
u2.on(n3).unsubscribe(o3), r3.apply(u2, e3);
};
return u2.on(n3, o3);
}, this.on.ready.subscribe = Y(this.on.ready.subscribe, function(o3) {
return function(n3, r3) {
D.vip(function() {
var t4, e3 = u2._state;
e3.openComplete ? (e3.dbOpenError || K.resolve().then(n3), r3 && o3(n3)) : e3.onReadyBeingFired ? (e3.onReadyBeingFired.push(n3), r3 && o3(n3)) : (o3(n3), t4 = u2, r3 || o3(function e4() {
t4.on.ready.unsubscribe(n3), t4.on.ready.unsubscribe(e4);
}));
});
};
}), this.Collection = (i2 = this, Kt(qt.prototype, function(e3, t4) {
this.db = i2;
var n3 = yt, r3 = null;
if (t4) try {
n3 = t4();
} catch (e4) {
r3 = e4;
}
var t4 = e3._ctx, e3 = t4.table, o3 = e3.hook.reading.fire;
this._ctx = { table: e3, index: t4.index, isPrimKey: !t4.index || e3.schema.primKey.keyPath && t4.index === e3.schema.primKey.name, range: n3, keysOnly: false, dir: "next", unique: "", algorithm: null, filter: null, replayFilter: null, justLimit: true, isMatch: null, offset: 0, limit: 1 / 0, error: r3, or: t4.or, valueMapper: o3 !== ve ? o3 : null };
})), this.Table = (r2 = this, Kt(Ot.prototype, function(e3, t4, n3) {
this.db = r2, this._tx = n3, this.name = e3, this.schema = t4, this.hook = r2._allTables[e3] ? r2._allTables[e3].hook : Pt(null, { creating: [ge, g], reading: [me, ve], updating: [_e, g], deleting: [we, g] });
})), this.Transaction = (a2 = this, Kt(Yt.prototype, function(e3, t4, n3, r3, o3) {
var i3 = this;
"readonly" !== e3 && t4.forEach(function(e4) {
e4 = null == (e4 = n3[e4]) ? void 0 : e4.yProps;
e4 && (t4 = t4.concat(e4.map(function(e5) {
return e5.updatesTable;
})));
}), this.db = a2, this.mode = e3, this.storeNames = t4, this.schema = n3, this.chromeTransactionDurability = r3, this.idbtrans = null, this.on = Pt(this, "complete", "error", "abort"), this.parent = o3 || 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 K(function(e4, t5) {
i3._resolve = e4, i3._reject = t5;
}), this._completion.then(function() {
i3.active = false, i3.on.complete.fire();
}, function(e4) {
var t5 = i3.active;
return i3.active = false, i3.on.error.fire(e4), i3.parent ? i3.parent._reject(e4) : t5 && i3.idbtrans && i3.idbtrans.abort(), S(e4);
});
})), this.Version = (n2 = this, Kt(mn.prototype, function(e3) {
this.db = n2, this._cfg = { version: e3, storesSource: null, dbschema: {}, tables: {}, contentUpgrade: null };
})), this.WhereClause = (o2 = this, Kt(Lt.prototype, function(e3, t4, n3) {
if (this.db = o2, this._ctx = { table: e3, index: ":id" === t4 ? null : t4, or: n3 }, this._cmp = this._ascending = C, this._descending = function(e4, t5) {
return C(t5, e4);
}, this._max = function(e4, t5) {
return 0 < C(e4, t5) ? e4 : t5;
}, this._min = function(e4, t5) {
return C(e4, t5) < 0 ? e4 : t5;
}, this._IDBKeyRange = o2._deps.IDBKeyRange, !this._IDBKeyRange) throw new k.MissingAPI();
})), this.on("versionchange", function(e3) {
0 < e3.newVersion ? console.warn("Another connection wants to upgrade database '".concat(u2.name, "'. Closing db now to resume the upgrade.")) : console.warn("Another connection wants to delete database '".concat(u2.name, "'. Closing db now to resume the delete request.")), u2.close({ disableAutoOpen: false });
}), this.on("blocked", function(e3) {
!e3.newVersion || e3.newVersion < e3.oldVersion ? console.warn("Dexie.delete('".concat(u2.name, "') was blocked")) : console.warn("Upgrade '".concat(u2.name, "' blocked by other connection holding version ").concat(e3.oldVersion / 10));
}), this._maxKey = Xt(t3.IDBKeyRange), this._createTransaction = function(e3, t4, n3, r3) {
return new u2.Transaction(e3, t4, n3, u2._options.chromeTransactionDurability, r3);
}, this._fireOnBlocked = function(t4) {
u2.on("blocked").fire(t4), gn.toArray().filter(function(e3) {
return e3.name === u2.name && e3 !== u2 && !e3._state.vcFired;
}).map(function(e3) {
return e3.on("versionchange").fire(t4);
});
}, this.use(Yn), this.use(nr), this.use(Gn), this.use(Ln), this.use(Vn), new Proxy(this, { get: function(e3, t4, n3) {
var r3;
return "_vip" === t4 || ("table" === t4 ? function(e4) {
return rr(u2.table(e4), l2);
} : (r3 = Reflect.get(e3, t4, n3)) instanceof Ot ? rr(r3, l2) : "tables" === t4 ? r3.map(function(e4) {
return rr(e4, l2);
}) : "_createTransaction" === t4 ? function() {
return rr(r3.apply(this, arguments), l2);
} : r3);
} }));
this.vip = l2, s2.forEach(function(e3) {
return e3(u2);
});
}
var or, Se = "undefined" != typeof Symbol && "observable" in Symbol ? Symbol.observable : "@@observable", ir = (ar.prototype.subscribe = function(e2, t3, n2) {
return this._subscribe(e2 && "function" != typeof e2 ? e2 : { next: e2, error: t3, complete: n2 });
}, ar.prototype[Se] = function() {
return this;
}, ar);
function ar(e2) {
this._subscribe = e2;
}
try {
or = { indexedDB: f.indexedDB || f.mozIndexedDB || f.webkitIndexedDB || f.msIndexedDB, IDBKeyRange: f.IDBKeyRange || f.webkitIDBKeyRange };
} catch (e2) {
or = { indexedDB: null, IDBKeyRange: null };
}
function ur(d2) {
var p2, y2 = false, e2 = new ir(function(r2) {
var o2 = ue(d2);
var i2, a2 = false, u2 = {}, s2 = {}, e3 = { get closed() {
return a2;
}, unsubscribe: function() {
a2 || (a2 = true, i2 && i2.abort(), c2 && Wt.storagemutated.unsubscribe(h2));
} }, c2 = (r2.start && r2.start(e3), false), l2 = function() {
return st(t3);
};
function f2() {
return jn(s2, u2);
}
var h2 = function(e4) {
Cn(u2, e4), f2() && l2();
}, t3 = function() {
var t4, n2, e4;
!a2 && or.indexedDB && (u2 = {}, t4 = {}, i2 && i2.abort(), i2 = new AbortController(), e4 = ((e5) => {
var t5 = $e();
try {
o2 && nt();
var n3 = v(d2, e5);
return n3 = o2 ? n3.finally(w) : n3;
} finally {
t5 && Qe();
}
})(n2 = { subscr: t4, signal: i2.signal, requery: l2, querier: d2, trans: null }), c2 || (Wt(zt, h2), c2 = true), Promise.resolve(e4).then(function(e5) {
y2 = true, p2 = e5, a2 || n2.signal.aborted || (f2() || (s2 = t4, f2()) ? l2() : (u2 = {}, st(function() {
return !a2 && r2.next && r2.next(e5);
})));
}, function(e5) {
y2 = false, ["DatabaseClosedError", "AbortError"].includes(null == e5 ? void 0 : e5.name) || a2 || st(function() {
a2 || r2.error && r2.error(e5);
});
}));
};
return setTimeout(l2, 0), e3;
});
return e2.hasValue = function() {
return y2;
}, e2.getValue = function() {
return p2;
}, e2;
}
var sr = y;
function cr(e2) {
var t3 = fr;
try {
fr = true, Wt.storagemutated.fire(e2), Bn(e2, true);
} finally {
fr = t3;
}
}
M(sr, _(_({}, e), { delete: function(e2) {
return new sr(e2, { addons: [] }).delete();
}, exists: function(e2) {
return new sr(e2, { addons: [] }).open().then(function(e3) {
return e3.close(), true;
}).catch("NoSuchDatabaseError", function() {
return false;
});
}, getDatabaseNames: function(e2) {
try {
return t3 = sr.dependencies, n2 = t3.indexedDB, t3 = t3.IDBKeyRange, (_n(n2) ? Promise.resolve(n2.databases()).then(function(e3) {
return e3.map(function(e4) {
return e4.name;
}).filter(function(e4) {
return e4 !== ft;
});
}) : wn(n2, t3).toCollection().primaryKeys()).then(e2);
} catch (e3) {
return S(new k.MissingAPI());
}
var t3, n2;
}, defineClass: function() {
return function(e2) {
a(this, e2);
};
}, ignoreTransaction: function(e2) {
return P.trans ? at(P.transless, e2) : e2();
}, vip: xn, async: function(t3) {
return function() {
try {
var e2 = Nn(t3.apply(this, arguments));
return e2 && "function" == typeof e2.then ? e2 : K.resolve(e2);
} catch (e3) {
return S(e3);
}
};
}, spawn: function(e2, t3, n2) {
try {
var r2 = Nn(e2.apply(n2, t3 || []));
return r2 && "function" == typeof r2.then ? r2 : K.resolve(r2);
} catch (e3) {
return S(e3);
}
}, currentTransaction: { get: function() {
return P.trans || null;
} }, waitFor: function(e2, t3) {
e2 = K.resolve("function" == typeof e2 ? sr.ignoreTransaction(e2) : e2).timeout(t3 || 6e4);
return P.trans ? P.trans.waitFor(e2) : e2;
}, Promise: K, debug: { get: function() {
return l;
}, set: function(e2) {
Oe(e2);
} }, derive: U, extend: a, props: M, override: Y, Events: Pt, on: Wt, liveQuery: ur, extendObservabilitySet: Cn, getByKeyPath: c, setByKeyPath: b, delByKeyPath: function(t3, e2) {
"string" == typeof e2 ? b(t3, e2, void 0) : "length" in e2 && [].map.call(e2, function(e3) {
b(t3, e3, void 0);
});
}, shallowClone: G, deepClone: ee, getObjectDiff: Un, cmp: C, asap: Q, minKey: -1 / 0, addons: [], connections: { get: gn.toArray }, errnames: de, dependencies: or, cache: Tn, semVer: "4.4.1", version: "4.4.1".split(".").map(function(e2) {
return parseInt(e2);
}).reduce(function(e2, t3, n2) {
return e2 + t3 / Math.pow(10, 2 * n2);
}) })), sr.maxKey = Xt(sr.dependencies.IDBKeyRange), "undefined" != typeof dispatchEvent && "undefined" != typeof addEventListener && (Wt(zt, function(e2) {
fr || (e2 = new CustomEvent(Vt, { detail: e2 }), fr = true, dispatchEvent(e2), fr = false);
}), addEventListener(Vt, function(e2) {
e2 = e2.detail;
fr || cr(e2);
}));
var lr, fr = false, hr = function() {
};
return "undefined" != typeof BroadcastChannel && ((hr = function() {
(lr = new BroadcastChannel(Vt)).onmessage = function(e2) {
return e2.data && cr(e2.data);
};
})(), "function" == typeof lr.unref && lr.unref(), Wt(zt, function(e2) {
fr || lr.postMessage(e2);
})), "undefined" != typeof addEventListener && (addEventListener("pagehide", function(e2) {
if (!y.disableBfCache && e2.persisted) {
l && console.debug("Dexie: handling persisted pagehide"), null != lr && lr.close();
for (var t3 = 0, n2 = gn.toArray(); t3 < n2.length; t3++) n2[t3].close({ disableAutoOpen: false });
}
}), addEventListener("pageshow", function(e2) {
!y.disableBfCache && e2.persisted && (l && console.debug("Dexie: handling persisted pageshow"), hr(), cr({ all: new q(-1 / 0, [[]]) }));
})), K.rejectionMapper = function(e2, t3) {
return !e2 || e2 instanceof ce || e2 instanceof TypeError || e2 instanceof SyntaxError || !e2.name || !ye[e2.name] ? e2 : (t3 = new ye[e2.name](t3 || e2.message, e2), "stack" in e2 && u(t3, "stack", { get: function() {
return this.inner.stack;
} }), t3);
}, Oe(l), _(y, Object.freeze({ __proto__: null, DEFAULT_MAX_CONNECTIONS: 1e3, Dexie: y, Entity: mt, PropModification: _t, RangeSet: q, add: function(e2) {
return new _t({ add: e2 });
}, cmp: C, default: y, liveQuery: ur, mergeRanges: Pn, rangesOverlap: Kn, remove: function(e2) {
return new _t({ remove: e2 });
}, replacePrefix: function(e2, t3) {
return new _t({ replacePrefix: [e2, t3] });
} }), { default: y }), y;
});
})(dexie_min$1);
return dexie_min$1.exports;
}
var dexie_minExports = requireDexie_min();
const _Dexie = getDefaultExportFromCjs(dexie_minExports);
const DexieSymbol = Symbol.for("Dexie");
const Dexie = globalThis[DexieSymbol] || (globalThis[DexieSymbol] = _Dexie);
if (_Dexie.semVer !== Dexie.semVer) {
throw new Error(`Two different versions of Dexie loaded in the same app: ${_Dexie.semVer} and ${Dexie.semVer}`);
}
const {
liveQuery,
mergeRanges,
rangesOverlap,
RangeSet,
cmp,
Entity,
PropModification,
replacePrefix,
add,
remove,
DexieYProvider
} = Dexie;
class MusicTrackerDB extends Dexie {
history;
constructor(name) {
super(name);
this.version(1).stores({
history: "key, artist, title"
});
}
}
class TrackDB {
db;
cache = new Map();
platformCounts = new Map();
syncGen = 0;
constructor(dbName = "MusicTracker") {
this.db = new MusicTrackerDB(dbName);
}
async init() {
await this.db.open();
if (typeof GM_getValue === "function") {
const clearVer = GM_getValue("tracksClearVer", 0);
const localVer = Number(localStorage.getItem("mt-clear-ver") ?? "0");
if (clearVer > localVer) {
await this.db.history.clear();
localStorage.setItem("mt-clear-ver", String(clearVer));
}
const gmTracks = GM_getValue("tracks", []);
if (Array.isArray(gmTracks) && gmTracks.length > 0) {
await this.mergeMax(gmTracks);
}
}
const all = await this.db.history.toArray();
this.cache.clear();
this.platformCounts.clear();
for (const record of all) {
this.cache.set(record.key, record.playCount);
for (const p of Object.keys(record.platforms ?? {})) {
this.platformCounts.set(p, (this.platformCounts.get(p) ?? 0) + 1);
}
}
}
async mergeMax(tracks) {
await this.db.transaction("rw", this.db.history, async () => {
const existing = await this.db.history.bulkGet(tracks.map((t2) => t2.key));
for (let i = 0; i < tracks.length; i++) {
const track = tracks[i];
if (!track.key) continue;
const ex = existing[i];
if (ex) {
if (track.playCount > ex.playCount) {
const merged = { ...ex.platforms };
for (const [p, ids] of Object.entries(track.platforms ?? {})) {
merged[p] = [... new Set([...merged[p] ?? [], ...ids])];
}
await this.db.history.update(track.key, {
playCount: track.playCount,
platforms: merged
});
}
} else {
await this.db.history.add({ ...track });
}
}
});
}
syncToGM() {
const gen = ++this.syncGen;
if (typeof GM_setValue === "function") {
this.db.history.toArray().then((tracks) => {
if (gen === this.syncGen) GM_setValue("tracks", tracks);
});
}
}
getPlayCount(key) {
return this.cache.get(key) ?? 0;
}
getUniqueCount() {
return this.cache.size;
}
getCountForPlatform(platform) {
return this.platformCounts.get(platform) ?? 0;
}
async get(key) {
const record = await this.db.history.get(key);
return record ?? null;
}
async getAll() {
return this.db.history.toArray();
}
async increment(key, artist, title, platform, platformId) {
const existing = await this.db.history.get(key);
if (existing) {
const platforms = { ...existing.platforms };
const isNewPlatform = !platforms[platform];
const ids = platforms[platform] ?? [];
if (!ids.includes(platformId)) {
ids.push(platformId);
}
platforms[platform] = ids;
const newCount = existing.playCount + 1;
await this.db.history.update(key, { playCount: newCount, platforms });
this.cache.set(key, newCount);
if (isNewPlatform) {
this.platformCounts.set(platform, (this.platformCounts.get(platform) ?? 0) + 1);
}
this.syncToGM();
return newCount;
}
const record = {
key,
artist,
title,
playCount: 1,
platforms: { [platform]: [platformId] }
};
await this.db.history.add(record);
this.cache.set(key, 1);
this.platformCounts.set(platform, (this.platformCounts.get(platform) ?? 0) + 1);
this.syncToGM();
return 1;
}
async importTracks(tracks) {
let added = 0;
let updated = 0;
for (const track of tracks) {
const existing = await this.db.history.get(track.key);
if (existing) {
const mergedPlatforms = { ...existing.platforms };
for (const [platform, ids] of Object.entries(track.platforms)) {
const existingIds = mergedPlatforms[platform] ?? [];
const mergedIds = [... new Set([...existingIds, ...ids])];
mergedPlatforms[platform] = mergedIds;
}
const newCount = existing.playCount + track.playCount;
await this.db.history.update(track.key, {
playCount: newCount,
platforms: mergedPlatforms
});
this.cache.set(track.key, newCount);
updated++;
} else {
await this.db.history.add({ ...track });
this.cache.set(track.key, track.playCount);
added++;
}
}
this.syncToGM();
return { added, updated };
}
async clearAll() {
++this.syncGen;
await this.db.history.clear();
this.cache.clear();
this.platformCounts.clear();
if (typeof GM_setValue === "function") {
GM_setValue("tracks", []);
GM_setValue("tracksClearVer", Date.now());
localStorage.setItem("mt-clear-ver", String(Date.now()));
}
}
async halvePlayCounts() {
const all = await this.db.history.toArray();
let affected = 0;
for (const record of all) {
if (record.playCount <= 1) continue;
const newCount = Math.max(1, Math.floor(record.playCount / 2));
await this.db.history.update(record.key, { playCount: newCount });
this.cache.set(record.key, newCount);
affected++;
}
this.syncToGM();
return affected;
}
}
class Tracker {
db;
settings;
timer = null;
cooldownMap = new Map();
currentKey = null;
onUpdated = null;
constructor(db, settings) {
this.db = db;
this.settings = settings;
}
setOnUpdated(cb) {
this.onUpdated = cb;
}
updateSettings(settings) {
this.settings = settings;
}
onTrackPlaying(key, artist, title, platform, platformId) {
if (key === this.currentKey && this.timer !== null) return;
this.clearTimer();
this.currentKey = key;
this.timer = setTimeout(() => {
this.timer = null;
this.tryCount(key, artist, title, platform, platformId);
}, this.settings.thresholdSeconds * 1e3);
}
onTrackStopped() {
this.clearTimer();
this.currentKey = null;
}
destroy() {
this.clearTimer();
}
async tryCount(key, artist, title, platform, platformId) {
const lastTime = this.cooldownMap.get(key) ?? 0;
const now = Date.now();
if (now - lastTime < this.settings.cooldownMinutes * 60 * 1e3) return;
const newCount = await this.db.increment(key, artist, title, platform, platformId);
this.cooldownMap.set(key, now);
if (this.onUpdated) {
this.onUpdated(key, newCount);
}
}
clearTimer() {
if (this.timer !== null) {
clearTimeout(this.timer);
this.timer = null;
}
}
}
const DEFAULT_SETTINGS = {
colorFrom: "#e8f5e9",
colorTo: "#4caf50",
maxAlpha: 0.4,
steps: 10,
cooldownMinutes: 3,
thresholdSeconds: 7,
language: "",
panelHidden: false
};
function getSettings() {
if (typeof GM_getValue === "function") {
const stored = GM_getValue("settings", null);
if (stored) return { ...DEFAULT_SETTINGS, ...stored };
}
return { ...DEFAULT_SETTINGS };
}
function saveSettings(settings) {
if (typeof GM_setValue === "function") {
GM_setValue("settings", settings);
}
}
function getPanelPosition() {
try {
const raw = localStorage.getItem("mt-panel-pos");
if (raw) return JSON.parse(raw);
} catch {
}
return { panelX: -1, panelY: -1 };
}
function savePanelPosition(pos) {
localStorage.setItem("mt-panel-pos", JSON.stringify(pos));
}
const CHANNEL_NAME = "music-tracker";
let channel = null;
let listener = null;
function initSync(onMessage) {
channel = new BroadcastChannel(CHANNEL_NAME);
listener = onMessage;
channel.onmessage = (event) => {
if (listener) listener(event.data);
};
}
function broadcast(msg) {
if (channel) channel.postMessage(msg);
}
function normalizeString(input) {
let s = input.toLowerCase().trim();
s = s.replace(/[\(\[]\s*(?:feat\.?|ft\.?)\s*[^\)\]]*[\)\]]/gi, "");
s = s.replace(/\s+/g, "");
s = s.replace(/[^\p{L}\p{N}]/gu, "");
return s;
}
function normalizeKey(artist, title) {
return `${normalizeString(artist)}—${normalizeString(title)}`;
}
const DEFAULT_MAX_ALPHA = 0.4;
function parseHexToRgb(hex) {
let h = hex.replace(/^#/, "");
if (h.length === 3) {
h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
}
return {
r: parseInt(h.slice(0, 2), 16),
g: parseInt(h.slice(2, 4), 16),
b: parseInt(h.slice(4, 6), 16)
};
}
function interpolateColor(from, to, t2) {
return {
r: Math.round(from.r + (to.r - from.r) * t2),
g: Math.round(from.g + (to.g - from.g) * t2),
b: Math.round(from.b + (to.b - from.b) * t2)
};
}
function playCountToColor(playCount, colorFrom, colorTo, steps, maxAlpha = DEFAULT_MAX_ALPHA) {
if (playCount <= 0) return "rgba(0, 0, 0, 0)";
const t2 = Math.min(playCount / steps, 1);
const from = parseHexToRgb(colorFrom);
const to = parseHexToRgb(colorTo);
const rgb = interpolateColor(from, to, t2);
const alpha = parseFloat((t2 * maxAlpha).toFixed(2));
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
}
function applyHighlight(element, playCount, colorFrom, colorTo, steps, maxAlpha = DEFAULT_MAX_ALPHA) {
const color = playCountToColor(playCount, colorFrom, colorTo, steps, maxAlpha);
element.style.backgroundColor = color;
}
const LOCALES = [
{ code: "en", name: "English" },
{ code: "ru", name: "Русский" },
{ code: "fr", name: "Français" },
{ code: "de", name: "Deutsch" },
{ code: "pl", name: "Polski" },
{ code: "ko", name: "한국어" },
{ code: "es", name: "Español" }
];
const translations = {
en: {
panelTitle: "Music Tracker",
tracks: "Tracks",
colorFrom: "Color from",
colorTo: "Color to",
steps: "Steps",
threshold: "Threshold (sec)",
cooldown: "Cooldown (min)",
language: "Language",
exportJson: "Export JSON",
importJson: "Import JSON",
clearHistory: "Clear History",
clearConfirm: "Clear all listening history?",
historyCleared: "History cleared",
exported: "Exported!",
importResult: (added, updated) => `+${added} added, ${updated} updated`,
importFailed: "Import failed",
invalidFormat: "Invalid file format",
tracker: "Activity",
normalize: "Normalize",
total: "total",
tipNormalize: "Halves play counts of all tracks (min 1)",
normalizeConfirm: "Halve all play counts? Tracks with 1 play will stay unchanged.",
normalizeResult: (count) => `${count} tracks normalized`,
alpha: "Opacity",
tipAlpha: "Maximum opacity of track highlighting",
tipColorFrom: "Start color for tracks with few listens",
tipColorTo: "End color for tracks with many listens",
tipSteps: "Number of listens to reach full color intensity",
tipThreshold: "Minimum seconds of listening to count as a play",
tipCooldown: "Minutes before the same track can be counted again"
},
ru: {
panelTitle: "Music Tracker",
tracks: "Треков",
colorFrom: "Цвет от",
colorTo: "Цвет до",
steps: "Шаги",
threshold: "Порог (сек)",
cooldown: "Кулдаун (мин)",
language: "Язык",
exportJson: "Экспорт JSON",
importJson: "Импорт JSON",
clearHistory: "Очистить историю",
clearConfirm: "Очистить всю историю прослушиваний?",
historyCleared: "История очищена",
exported: "Экспортировано!",
importResult: (added, updated) => `+${added} добавлено, ${updated} обновлено`,
importFailed: "Ошибка импорта",
invalidFormat: "Неверный формат файла",
tracker: "Активность",
normalize: "Усреднить",
total: "всего",
tipNormalize: "Уменьшает счётчики прослушиваний вдвое (минимум 1)",
normalizeConfirm: "Уменьшить все счётчики вдвое? Треки с 1 прослушиванием не изменятся.",
normalizeResult: (count) => `${count} треков усреднено`,
alpha: "Непрозрачность",
tipAlpha: "Максимальная непрозрачность подсветки треков",
tipColorFrom: "Начальный цвет для треков с малым числом прослушиваний",
tipColorTo: "Конечный цвет для треков с большим числом прослушиваний",
tipSteps: "Количество прослушиваний для достижения полного цвета",
tipThreshold: "Минимум секунд прослушивания для засчёта",
tipCooldown: "Минуты до повторного засчёта того же трека"
},
fr: {
panelTitle: "Music Tracker",
tracks: "Pistes",
colorFrom: "Couleur de",
colorTo: "Couleur à",
steps: "Étapes",
threshold: "Seuil (sec)",
cooldown: "Cooldown (min)",
language: "Langue",
exportJson: "Exporter JSON",
importJson: "Importer JSON",
clearHistory: "Effacer l'historique",
clearConfirm: "Effacer tout l'historique d'écoute?",
historyCleared: "Historique effacé",
exported: "Exporté!",
importResult: (added, updated) => `+${added} ajoutés, ${updated} mis à jour`,
importFailed: "Échec de l'importation",
invalidFormat: "Format de fichier invalide",
tracker: "Activité",
normalize: "Normaliser",
total: "au total",
tipNormalize: "Divise par deux les compteurs de toutes les pistes (min 1)",
normalizeConfirm: "Diviser tous les compteurs par deux ?",
normalizeResult: (count) => `${count} pistes normalisées`,
alpha: "Opacité",
tipAlpha: "Opacité maximale de la surbrillance",
tipColorFrom: "Couleur de départ pour les pistes peu écoutées",
tipColorTo: "Couleur finale pour les pistes très écoutées",
tipSteps: "Nombre d'écoutes pour atteindre la couleur maximale",
tipThreshold: "Secondes minimum d'écoute pour compter",
tipCooldown: "Minutes avant de recompter la même piste"
},
de: {
panelTitle: "Music Tracker",
tracks: "Titel",
colorFrom: "Farbe von",
colorTo: "Farbe bis",
steps: "Schritte",
threshold: "Schwelle (Sek)",
cooldown: "Cooldown (Min)",
language: "Sprache",
exportJson: "JSON exportieren",
importJson: "JSON importieren",
clearHistory: "Verlauf löschen",
clearConfirm: "Gesamten Hörverlauf löschen?",
historyCleared: "Verlauf gelöscht",
exported: "Exportiert!",
importResult: (added, updated) => `+${added} hinzugefügt, ${updated} aktualisiert`,
importFailed: "Import fehlgeschlagen",
invalidFormat: "Ungültiges Dateiformat",
tracker: "Aktivität",
normalize: "Normalisieren",
total: "gesamt",
tipNormalize: "Halbiert die Wiedergabezähler aller Titel (min 1)",
normalizeConfirm: "Alle Zähler halbieren?",
normalizeResult: (count) => `${count} Titel normalisiert`,
alpha: "Deckkraft",
tipAlpha: "Maximale Deckkraft der Hervorhebung",
tipColorFrom: "Startfarbe für selten gehörte Titel",
tipColorTo: "Endfarbe für oft gehörte Titel",
tipSteps: "Anzahl Wiedergaben bis zur vollen Farbintensität",
tipThreshold: "Mindest-Sekunden zum Zählen als Wiedergabe",
tipCooldown: "Minuten bis derselbe Titel erneut gezählt wird"
},
pl: {
panelTitle: "Music Tracker",
tracks: "Utworów",
colorFrom: "Kolor od",
colorTo: "Kolor do",
steps: "Kroki",
threshold: "Próg (sek)",
cooldown: "Cooldown (min)",
language: "Język",
exportJson: "Eksport JSON",
importJson: "Import JSON",
clearHistory: "Wyczyść historię",
clearConfirm: "Wyczyścić całą historię słuchania?",
historyCleared: "Historia wyczyszczona",
exported: "Wyeksportowano!",
importResult: (added, updated) => `+${added} dodano, ${updated} zaktualizowano`,
importFailed: "Błąd importu",
invalidFormat: "Nieprawidłowy format pliku",
tracker: "Aktywność",
normalize: "Normalizuj",
total: "łącznie",
tipNormalize: "Zmniejsza liczniki odtworzeń o połowę (min 1)",
normalizeConfirm: "Zmniejszyć wszystkie liczniki o połowę?",
normalizeResult: (count) => `${count} utworów znormalizowano`,
alpha: "Krycie",
tipAlpha: "Maksymalne krycie podświetlenia",
tipColorFrom: "Kolor początkowy dla rzadko słuchanych utworów",
tipColorTo: "Kolor końcowy dla często słuchanych utworów",
tipSteps: "Liczba odtworzeń do pełnej intensywności koloru",
tipThreshold: "Minimalna liczba sekund do zaliczenia odtworzenia",
tipCooldown: "Minuty przed ponownym zliczeniem tego samego utworu"
},
ko: {
panelTitle: "Music Tracker",
tracks: "트랙",
colorFrom: "시작 색상",
colorTo: "끝 색상",
steps: "단계",
threshold: "임계값 (초)",
cooldown: "쿨다운 (분)",
language: "언어",
exportJson: "JSON 내보내기",
importJson: "JSON 가져오기",
clearHistory: "기록 지우기",
clearConfirm: "모든 청취 기록을 지우시겠습니까?",
historyCleared: "기록이 지워졌습니다",
exported: "내보냈습니다!",
importResult: (added, updated) => `+${added} 추가, ${updated} 업데이트`,
importFailed: "가져오기 실패",
invalidFormat: "잘못된 파일 형식",
tracker: "활동",
normalize: "정규화",
total: "전체",
tipNormalize: "모든 트랙의 재생 횟수를 반으로 줄입니다 (최소 1)",
normalizeConfirm: "모든 재생 횟수를 반으로 줄일까요?",
normalizeResult: (count) => `${count}개 트랙 정규화됨`,
alpha: "불투명도",
tipAlpha: "하이라이트의 최대 불투명도",
tipColorFrom: "적게 들은 트랙의 시작 색상",
tipColorTo: "많이 들은 트랙의 끝 색상",
tipSteps: "최대 색상에 도달하는 재생 횟수",
tipThreshold: "재생으로 인정되는 최소 초",
tipCooldown: "같은 트랙을 다시 카운트하기까지의 분"
},
es: {
panelTitle: "Music Tracker",
tracks: "Pistas",
colorFrom: "Color desde",
colorTo: "Color hasta",
steps: "Pasos",
threshold: "Umbral (seg)",
cooldown: "Cooldown (min)",
language: "Idioma",
exportJson: "Exportar JSON",
importJson: "Importar JSON",
clearHistory: "Borrar historial",
clearConfirm: "¿Borrar todo el historial de escucha?",
historyCleared: "Historial borrado",
exported: "¡Exportado!",
importResult: (added, updated) => `+${added} añadidos, ${updated} actualizados`,
importFailed: "Error al importar",
invalidFormat: "Formato de archivo inválido",
tracker: "Actividad",
normalize: "Normalizar",
total: "en total",
tipNormalize: "Reduce a la mitad los contadores de todas las pistas (mín 1)",
normalizeConfirm: "¿Reducir todos los contadores a la mitad?",
normalizeResult: (count) => `${count} pistas normalizadas`,
alpha: "Opacidad",
tipAlpha: "Opacidad máxima del resaltado",
tipColorFrom: "Color inicial para pistas con pocas escuchas",
tipColorTo: "Color final para pistas con muchas escuchas",
tipSteps: "Número de escuchas para alcanzar el color máximo",
tipThreshold: "Segundos mínimos de escucha para contar",
tipCooldown: "Minutos antes de volver a contar la misma pista"
}
};
function detectLocale() {
const browserLang = navigator.language.toLowerCase().split("-")[0];
const supported = LOCALES.map((l) => l.code);
if (supported.includes(browserLang)) return browserLang;
return "en";
}
function t(locale) {
return translations[locale];
}
class Panel {
db;
platform;
container = null;
collapsed = true;
onSettingsChanged = null;
onImported = null;
hasDragged = false;
dragOffsetX = 0;
dragOffsetY = 0;
rafId = null;
pendingLeft = 0;
pendingTop = 0;
visibilityChecker = null;
visibilityInterval = null;
isVisible = true;
constructor(db, platform) {
this.db = db;
this.platform = platform;
}
setOnSettingsChanged(cb) {
this.onSettingsChanged = cb;
}
setOnImported(cb) {
this.onImported = cb;
}
setVisibilityChecker(checker) {
this.visibilityChecker = checker;
this.startVisibilityPoll();
}
mount() {
if (getSettings().panelHidden) return;
this.createAndAttach();
}
createAndAttach() {
this.container = document.createElement("div");
this.container.className = "mt-panel mt-panel--collapsed";
this.collapsed = true;
this.isVisible = true;
this.render();
this.setupDrag();
this.applyPosition();
document.body.appendChild(this.container);
window.addEventListener("resize", () => this.clampToViewport());
}
toggleVisibility() {
const settings = getSettings();
settings.panelHidden = !settings.panelHidden;
saveSettings(settings);
if (settings.panelHidden) {
this.container?.remove();
this.container = null;
} else {
this.createAndAttach();
if (this.visibilityChecker) this.startVisibilityPoll();
}
}
updateStat() {
if (!this.container || this.collapsed) return;
const stat = this.container.querySelector(".mt-stat");
if (!stat) return;
const locale = this.getLocale();
const i = t(locale);
const platformCount = this.db.getCountForPlatform(this.platform);
const totalCount = this.db.getUniqueCount();
const statExtra = totalCount > platformCount ? ` <span style="color:#999">(${totalCount} ${i.total})</span>` : "";
stat.innerHTML = `${i.tracks}: <strong>${platformCount}</strong>${statExtra}`;
}
getLocale() {
const settings = getSettings();
return settings.language || detectLocale();
}
applyPosition() {
if (!this.container) return;
const pos = getPanelPosition();
this.container.style.right = "auto";
if (pos.panelX >= 0 && pos.panelY >= 0) {
this.container.style.left = `${pos.panelX}px`;
this.container.style.top = `${pos.panelY}px`;
this.container.style.bottom = "auto";
} else {
this.container.style.left = "20px";
this.container.style.top = "auto";
this.container.style.bottom = "20px";
}
}
clampToViewport() {
if (!this.container) return;
const rect = this.container.getBoundingClientRect();
let left = rect.left;
let top = rect.top;
let adjusted = false;
if (rect.right > window.innerWidth) {
left = Math.max(0, window.innerWidth - rect.width - 4);
adjusted = true;
}
if (rect.bottom > window.innerHeight) {
top = Math.max(0, window.innerHeight - rect.height - 4);
adjusted = true;
}
if (left < 0) {
left = 4;
adjusted = true;
}
if (top < 0) {
top = 4;
adjusted = true;
}
if (adjusted) {
this.container.style.left = `${left}px`;
this.container.style.top = `${top}px`;
this.container.style.bottom = "auto";
this.container.style.right = "auto";
}
}
setupDrag() {
if (!this.container) return;
this.container.addEventListener("mousedown", (e) => {
if (!this.collapsed) return;
if (e.target.closest(".mt-close-badge")) return;
this.hasDragged = false;
const rect = this.container.getBoundingClientRect();
this.dragOffsetX = e.clientX - rect.left;
this.dragOffsetY = e.clientY - rect.top;
this.container.classList.add("mt-panel--dragging");
const onMouseMove = (ev) => {
if (!this.container) return;
let left = ev.clientX - this.dragOffsetX;
let top = ev.clientY - this.dragOffsetY;
if (!this.hasDragged) {
const curRect = this.container.getBoundingClientRect();
if (Math.abs(left - curRect.left) < 5 && Math.abs(top - curRect.top) < 5) return;
this.hasDragged = true;
}
const w = this.container.offsetWidth;
const h = this.container.offsetHeight;
left = Math.max(0, Math.min(left, window.innerWidth - w));
top = Math.max(0, Math.min(top, window.innerHeight - h));
this.pendingLeft = left;
this.pendingTop = top;
if (this.rafId === null) {
this.rafId = requestAnimationFrame(() => {
if (this.container) {
this.container.style.left = `${this.pendingLeft}px`;
this.container.style.top = `${this.pendingTop}px`;
this.container.style.right = "auto";
this.container.style.bottom = "auto";
}
this.rafId = null;
});
}
};
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
if (this.rafId !== null) {
cancelAnimationFrame(this.rafId);
this.rafId = null;
}
this.container?.classList.remove("mt-panel--dragging");
if (this.hasDragged && this.container) {
this.container.style.left = `${this.pendingLeft}px`;
this.container.style.top = `${this.pendingTop}px`;
this.container.style.right = "auto";
this.container.style.bottom = "auto";
savePanelPosition({
panelX: Math.round(this.pendingLeft),
panelY: Math.round(this.pendingTop)
});
}
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
}
noContentCount = 0;
startVisibilityPoll() {
if (this.visibilityInterval) clearInterval(this.visibilityInterval);
this.visibilityInterval = setInterval(() => {
if (!this.visibilityChecker || !this.container) return;
const shouldShow = this.visibilityChecker();
if (shouldShow) {
this.noContentCount = 0;
} else {
this.noContentCount++;
}
const actuallyShow = shouldShow || this.noContentCount < 3;
if (actuallyShow !== this.isVisible) {
this.isVisible = actuallyShow;
if (this.collapsed) {
this.container.style.display = actuallyShow ? "" : "none";
}
}
}, 1e3);
}
hideForever() {
const settings = getSettings();
settings.panelHidden = true;
saveSettings(settings);
this.container?.remove();
this.container = null;
}
render() {
if (!this.container) return;
const locale = this.getLocale();
const i = t(locale);
if (this.collapsed) {
this.container.className = "mt-panel mt-panel--collapsed";
this.container.innerHTML = `${i.tracker}<button class="mt-close-badge">×</button>`;
this.container.onclick = (e) => {
if (e.target.closest(".mt-close-badge")) {
e.stopPropagation();
this.hideForever();
return;
}
if (this.hasDragged) {
this.hasDragged = false;
return;
}
this.collapsed = false;
this.render();
};
if (!this.isVisible) {
this.container.style.display = "none";
}
this.applyPosition();
return;
}
this.container.className = "mt-panel";
this.container.onclick = null;
this.container.style.display = "";
this.container.style.overflow = "";
const pos = getPanelPosition();
const startLeft = pos.panelX >= 0 ? pos.panelX : 20;
const startTop = pos.panelY >= 0 ? pos.panelY : window.innerHeight - 350;
this.container.style.left = `${startLeft}px`;
this.container.style.top = `${startTop}px`;
this.container.style.right = "auto";
this.container.style.bottom = "auto";
const settings = getSettings();
const platformCount = this.db.getCountForPlatform(this.platform);
const totalCount = this.db.getUniqueCount();
const statExtra = totalCount > platformCount ? ` <span style="color:#999">(${totalCount} ${i.total})</span>` : "";
const langOptions = LOCALES.map(
(l) => `<option value="${l.code}" ${l.code === locale ? "selected" : ""}>${l.name}</option>`
).join("");
this.container.innerHTML = `
<div class="mt-header">
<span>${i.panelTitle}</span>
<button class="mt-collapse-btn">×</button>
</div>
<div class="mt-body">
<div class="mt-stat">${i.tracks}: <strong>${platformCount}</strong>${statExtra}</div>
<div class="mt-gradient-preview" style="background: linear-gradient(to right, ${settings.colorFrom}, ${settings.colorTo})"></div>
<div class="mt-field">
<label>${i.alpha} <span class="mt-help" data-tip="${i.tipAlpha}">?</span></label>
<input type="range" min="0.05" max="1" step="0.01" value="${settings.maxAlpha}" data-setting="maxAlpha" class="mt-alpha-slider" />
</div>
<div class="mt-field">
<label>${i.colorFrom} <span class="mt-help" data-tip="${i.tipColorFrom}">?</span></label>
<input type="color" value="${settings.colorFrom}" data-setting="colorFrom" />
</div>
<div class="mt-field">
<label>${i.colorTo} <span class="mt-help" data-tip="${i.tipColorTo}">?</span></label>
<input type="color" value="${settings.colorTo}" data-setting="colorTo" />
</div>
<div class="mt-field">
<label>${i.steps} <span class="mt-help" data-tip="${i.tipSteps}">?</span></label>
<input type="number" value="${settings.steps}" min="1" max="100" data-setting="steps" />
</div>
<div class="mt-field">
<label>${i.threshold} <span class="mt-help" data-tip="${i.tipThreshold}">?</span></label>
<input type="number" value="${settings.thresholdSeconds}" min="1" max="60" data-setting="thresholdSeconds" />
</div>
<div class="mt-field">
<label>${i.cooldown} <span class="mt-help" data-tip="${i.tipCooldown}">?</span></label>
<input type="number" value="${settings.cooldownMinutes}" min="0" max="60" data-setting="cooldownMinutes" />
</div>
<div class="mt-field">
<label>${i.language}</label>
<select class="mt-lang-select" data-setting="language">
${langOptions}
</select>
</div>
<div class="mt-buttons">
<button class="mt-btn mt-btn--primary mt-export-btn">${i.exportJson}</button>
<label class="mt-btn mt-btn--secondary" style="cursor:pointer">
${i.importJson}
<input type="file" accept=".json" class="mt-import-input" />
</label>
<button class="mt-btn mt-btn--secondary mt-normalize-btn" title="${i.tipNormalize}">${i.normalize} <span class="mt-help" data-tip="${i.tipNormalize}">?</span></button>
<button class="mt-btn mt-btn--danger mt-clear-btn">${i.clearHistory}</button>
</div>
</div>
`;
this.bindEvents();
requestAnimationFrame(() => this.clampToViewport());
}
bindEvents() {
if (!this.container) return;
const locale = this.getLocale();
const i = t(locale);
this.container.querySelector(".mt-collapse-btn")?.addEventListener("click", (e) => {
e.stopPropagation();
e.preventDefault();
this.collapsed = true;
this.render();
});
this.container.querySelectorAll("[data-setting]").forEach((input) => {
const isLive = input instanceof HTMLInputElement && (input.type === "range" || input.type === "color");
const handler = (live) => {
const key = input.dataset.setting;
const settings = getSettings();
if (input instanceof HTMLInputElement && (input.type === "number" || input.type === "range")) {
settings[key] = Number(input.value);
} else {
settings[key] = input.value;
}
saveSettings(settings);
if (live) {
const preview = this.container?.querySelector(".mt-gradient-preview");
if (preview) preview.style.background = `linear-gradient(to right, ${settings.colorFrom}, ${settings.colorTo})`;
if (this.onSettingsChanged) this.onSettingsChanged(settings);
} else {
this.render();
if (this.onSettingsChanged) this.onSettingsChanged(settings);
}
};
if (isLive && input instanceof HTMLInputElement && input.type === "range") {
input.addEventListener("input", () => handler(true));
} else if (input instanceof HTMLInputElement && input.type === "color") {
let poll = null;
let lastVal = input.value;
input.addEventListener("focus", () => {
lastVal = input.value;
poll = setInterval(() => {
if (input.value !== lastVal) {
lastVal = input.value;
handler(true);
}
}, 50);
});
const stopPoll = () => {
if (poll) {
clearInterval(poll);
poll = null;
}
};
input.addEventListener("blur", stopPoll);
input.addEventListener("change", () => {
stopPoll();
handler(false);
});
} else {
input.addEventListener("change", () => handler(false));
}
});
this.container.querySelector(".mt-export-btn")?.addEventListener("click", () => {
this.exportData();
});
this.container.querySelector(".mt-import-input")?.addEventListener("change", (e) => {
const file = e.target.files?.[0];
if (file) this.importData(file);
});
this.container.querySelector(".mt-clear-btn")?.addEventListener("click", () => {
if (confirm(i.clearConfirm)) {
this.db.clearAll().then(() => {
this.showToast(i.historyCleared);
this.render();
if (this.onImported) this.onImported();
});
}
});
this.container.querySelector(".mt-normalize-btn")?.addEventListener("click", () => {
if (confirm(i.normalizeConfirm)) {
this.db.halvePlayCounts().then((count) => {
this.showToast(i.normalizeResult(count));
this.render();
if (this.onImported) this.onImported();
});
}
});
}
async exportData() {
const tracks = await this.db.getAll();
const data = {
version: 1,
exportedAt: ( new Date()).toISOString(),
tracks
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `music-tracker-${( new Date()).toISOString().slice(0, 10)}.json`;
a.click();
URL.revokeObjectURL(url);
}
async importData(file) {
const locale = this.getLocale();
const i = t(locale);
try {
const text = await file.text();
const data = JSON.parse(text);
if (!data.version || !Array.isArray(data.tracks)) {
this.showToast(i.invalidFormat);
return;
}
const result = await this.db.importTracks(data.tracks);
this.showToast(i.importResult(result.added, result.updated));
this.render();
if (this.onImported) this.onImported();
} catch {
this.showToast(i.importFailed);
}
}
showToast(message) {
const toast = document.createElement("div");
toast.className = "mt-toast";
toast.textContent = message;
document.body.appendChild(toast);
requestAnimationFrame(() => toast.classList.add("mt-toast--visible"));
setTimeout(() => {
toast.classList.remove("mt-toast--visible");
setTimeout(() => toast.remove(), 300);
}, 2500);
}
}
function injectStyles() {
const css = `
.mt-panel {
position: fixed;
width: 260px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 24px rgba(0,0,0,0.15);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 13px;
color: #333;
z-index: 2147483646;
overflow: visible;
}
.mt-panel--collapsed {
width: auto;
height: auto;
padding: 8px 16px;
border-radius: 8px;
cursor: grab;
display: flex;
align-items: center;
justify-content: center;
background: #4caf50;
color: #fff;
font-weight: 600;
font-size: 13px;
user-select: none;
overflow: visible;
}
.mt-panel--collapsed:active {
cursor: grabbing;
}
.mt-panel--dragging {
transition: none !important;
}
.mt-close-badge {
position: absolute;
top: -7px;
right: -7px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #c62828;
color: #fff;
font-size: 11px;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 2px;
cursor: pointer;
border: 1.5px solid #fff;
box-sizing: border-box;
opacity: 0;
transition: opacity 0.15s;
z-index: 1;
}
.mt-panel--collapsed:hover .mt-close-badge {
opacity: 1;
}
.mt-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
background: #4caf50;
color: #fff;
font-weight: 600;
font-size: 14px;
border-radius: 12px 12px 0 0;
}
.mt-header button {
background: none;
border: none;
color: #fff;
cursor: pointer;
font-size: 18px;
line-height: 1;
padding: 0;
}
.mt-body {
padding: 12px 14px;
}
.mt-stat {
margin-bottom: 10px;
font-size: 13px;
color: #666;
}
.mt-gradient-preview {
height: 8px;
border-radius: 4px;
margin-bottom: 12px;
}
.mt-field {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.mt-field label {
font-size: 12px;
color: #555;
display: flex;
align-items: center;
gap: 4px;
}
.mt-help {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 12px;
height: 12px;
border-radius: 50%;
background: #ccc;
color: #666;
font-size: 8px;
font-weight: 700;
cursor: help;
flex-shrink: 0;
}
.mt-field {
position: relative;
}
.mt-buttons {
position: relative;
}
.mt-help::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 4px);
left: 0;
right: 0;
background: #333;
color: #fff;
font-size: 10px;
font-weight: 400;
padding: 4px 6px;
border-radius: 4px;
white-space: normal;
width: auto;
pointer-events: none;
opacity: 0;
z-index: 2147483647;
line-height: 1.3;
}
.mt-buttons .mt-help {
position: static;
}
.mt-field .mt-help {
position: static;
}
.mt-field .mt-help::after {
position: absolute;
left: 0;
right: 0;
bottom: calc(100% + 8px);
width: auto;
max-width: none;
}
.mt-help:hover::after {
opacity: 1;
}
.mt-field input[type="color"] {
width: 32px;
height: 24px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
padding: 0;
}
.mt-field input[type="number"] {
width: 60px;
padding: 3px 6px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
text-align: center;
color: #333;
background: #fff;
}
.mt-buttons {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 10px;
}
.mt-btn {
padding: 7px 12px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
text-align: center;
transition: background 0.15s;
}
.mt-btn--primary {
background: #4caf50;
color: #fff;
}
.mt-btn--primary:hover { background: #43a047; }
.mt-btn--secondary {
background: #e8f5e9;
color: #2e7d32;
}
.mt-btn--secondary:hover { background: #c8e6c9; }
.mt-btn--danger {
background: #ffebee;
color: #c62828;
}
.mt-btn--danger:hover { background: #ffcdd2; }
.mt-lang-select {
width: 100px;
padding: 3px 6px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: #fff;
color: #333;
cursor: pointer;
}
.mt-alpha-slider {
width: 100px;
cursor: pointer;
accent-color: #4caf50;
}
.mt-import-input {
display: none;
}
.mt-toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #333;
color: #fff;
padding: 10px 20px;
border-radius: 8px;
font-size: 14px;
z-index: 2147483647;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
.mt-toast--visible { opacity: 1; }
`;
const style = document.createElement("style");
style.textContent = css;
document.head.appendChild(style);
}
function parseAudioRow(element) {
const raw = element.getAttribute("data-audio");
if (raw) {
let data;
try {
data = JSON.parse(raw);
} catch {
return null;
}
if (!Array.isArray(data)) return null;
const title = String(data[3] ?? "").trim();
const artist = String(data[4] ?? "").trim();
if (!title || !artist) return null;
const fullId = element.getAttribute("data-full-id") ?? `${data[1]}_${data[0]}`;
return { artist, title, platformId: fullId };
}
const titleEl = element.querySelector('[class*="SecondaryAttachment__titleText"]');
const artistEl = element.querySelector('[class*="SecondaryAttachment__description"]');
if (titleEl && artistEl) {
const title = titleEl.textContent?.trim() ?? "";
const artist = artistEl.textContent?.trim() ?? "";
if (!title || !artist) return null;
return { artist, title, platformId: `vk_${artist}_${title}` };
}
return null;
}
function findAllAudioRows(root = document) {
const classic = Array.from(root.querySelectorAll(".audio_row[data-audio]"));
const react = Array.from(root.querySelectorAll('[class*="vkitSecondaryAttachment__root"]'));
return [...classic, ...react];
}
function findPlayingRow$3(root = document) {
const classic = root.querySelector(".audio_row.audio_row__playing");
if (classic) return classic;
const reactItems = root.querySelectorAll('[class*="vkitSecondaryAttachment__root"]');
for (const item of reactItems) {
const timeEl = item.querySelector('[class*="AudioPlayerPlaybackProgressTime"]');
if (timeEl?.textContent?.trim()) return item;
}
return null;
}
function hasMusicContent$4(root = document) {
return findAllAudioRows(root).length > 0;
}
class VKObserver {
mutationObserver = null;
playingPollInterval = null;
rescanInterval = null;
onNewRows;
onPlayingChanged;
processedRows = new WeakSet();
currentPlayingId = null;
debounceTimer = null;
constructor(onNewRows, onPlayingChanged) {
this.onNewRows = onNewRows;
this.onPlayingChanged = onPlayingChanged;
}
start() {
this.scanExistingRows();
this.startMutationObserver();
this.startPlayingPoll();
this.startRescanPoll();
}
stop() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
this.mutationObserver = null;
}
if (this.playingPollInterval) {
clearInterval(this.playingPollInterval);
this.playingPollInterval = null;
}
if (this.rescanInterval) {
clearInterval(this.rescanInterval);
this.rescanInterval = null;
}
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
scanExistingRows() {
const rows = findAllAudioRows();
const newRows = rows.filter((r) => !this.processedRows.has(r));
const valid = newRows.filter((r) => parseAudioRow(r) !== null);
for (const row of valid) this.processedRows.add(row);
if (valid.length > 0) this.onNewRows(valid);
}
startMutationObserver() {
this.mutationObserver = new MutationObserver(() => {
if (this.debounceTimer) clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.debounceTimer = null;
this.scanExistingRows();
}, 200);
});
this.mutationObserver.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["class"]
});
}
startRescanPoll() {
this.rescanInterval = setInterval(() => this.scanExistingRows(), 2e3);
}
startPlayingPoll() {
this.playingPollInterval = setInterval(() => {
const playing = findPlayingRow$3();
let playingId = null;
if (playing) {
playingId = playing.getAttribute("data-full-id");
if (!playingId) {
const info = parseAudioRow(playing);
playingId = info ? `react_${info.artist}_${info.title}` : null;
}
}
if (playingId !== this.currentPlayingId) {
this.currentPlayingId = playingId;
this.onPlayingChanged(playing);
}
}, 500);
}
}
class VKPlatform {
db;
tracker;
observer = null;
constructor(db, tracker) {
this.db = db;
this.tracker = tracker;
}
start() {
this.observer = new VKObserver(
(rows) => this.handleNewRows(rows),
(row) => this.handlePlayingChanged(row)
);
this.observer.start();
}
stop() {
this.observer?.stop();
this.tracker.destroy();
}
rehighlightAll() {
const settings = getSettings();
const rows = findAllAudioRows();
for (const row of rows) {
const info = parseAudioRow(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handleNewRows(rows) {
const settings = getSettings();
for (const row of rows) {
const info = parseAudioRow(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handlePlayingChanged(row) {
if (!row) {
this.tracker.onTrackStopped();
return;
}
const info = parseAudioRow(row);
if (!info) return;
const key = normalizeKey(info.artist, info.title);
this.tracker.onTrackPlaying(key, info.artist, info.title, "vk", info.platformId);
}
rehighlightKey(key) {
const settings = getSettings();
const count = this.db.getPlayCount(key);
const rows = findAllAudioRows();
for (const row of rows) {
const info = parseAudioRow(row);
if (!info) continue;
const rowKey = normalizeKey(info.artist, info.title);
if (rowKey === key) {
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
}
}
function parseTrackRow$2(element) {
const titleEl = element.querySelector('[class*="Meta_title__"]');
if (!titleEl) return null;
const title = titleEl.textContent?.trim() ?? "";
const artistEls = element.querySelectorAll('[class*="Meta_artistCaption__"]');
const artist = Array.from(artistEls).map((el) => el.textContent?.trim()).filter(Boolean).join(", ");
if (!title || !artist) return null;
const link = element.querySelector('a[class*="Meta_albumLink__"]');
const href = link?.getAttribute("href") ?? "";
const match = href.match(/\/album\/(\d+)\/track\/(\d+)/);
const platformId = match ? `${match[1]}_${match[2]}` : `ym_${artist}_${title}`;
return { artist, title, platformId };
}
function findAllTrackRows$2(root = document) {
return Array.from(root.querySelectorAll('[class*="CommonTrack_root"]'));
}
function findPlayingRow$2(root = document) {
const anim = root.querySelector(
'[class*="PlayingAnimation_root"]:not([class*="stopAnimation"])'
);
if (!anim) return null;
return anim.closest('[class*="CommonTrack_root"]');
}
function hasMusicContent$3() {
return true;
}
class YandexObserver {
mutationObserver = null;
playingPollInterval = null;
onNewRows;
onPlayingChanged;
processedRows = new WeakSet();
currentPlayingId = null;
debounceTimer = null;
constructor(onNewRows, onPlayingChanged) {
this.onNewRows = onNewRows;
this.onPlayingChanged = onPlayingChanged;
}
start() {
this.scanExistingRows();
this.startMutationObserver();
this.startPlayingPoll();
}
stop() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
this.mutationObserver = null;
}
if (this.playingPollInterval) {
clearInterval(this.playingPollInterval);
this.playingPollInterval = null;
}
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
scanExistingRows() {
const rows = findAllTrackRows$2();
const newRows = rows.filter((r) => !this.processedRows.has(r));
for (const row of newRows) this.processedRows.add(row);
if (newRows.length > 0) this.onNewRows(newRows);
}
startMutationObserver() {
this.mutationObserver = new MutationObserver(() => {
if (this.debounceTimer) clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.debounceTimer = null;
this.scanExistingRows();
}, 300);
});
this.mutationObserver.observe(document.body, {
childList: true,
subtree: true
});
}
startPlayingPoll() {
this.playingPollInterval = setInterval(() => {
const playing = findPlayingRow$2();
const link = playing?.querySelector('a[class*="Meta_albumLink__"]');
const playingId = link?.getAttribute("href") ?? null;
if (playingId !== this.currentPlayingId) {
this.currentPlayingId = playingId;
this.onPlayingChanged(playing);
}
}, 500);
}
}
class YandexPlatform {
db;
tracker;
observer = null;
constructor(db, tracker) {
this.db = db;
this.tracker = tracker;
}
start() {
this.observer = new YandexObserver(
(rows) => this.handleNewRows(rows),
(row) => this.handlePlayingChanged(row)
);
this.observer.start();
}
stop() {
this.observer?.stop();
this.tracker.destroy();
}
rehighlightAll() {
const settings = getSettings();
const rows = findAllTrackRows$2();
for (const row of rows) {
const info = parseTrackRow$2(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
rehighlightKey(key) {
const settings = getSettings();
const count = this.db.getPlayCount(key);
const rows = findAllTrackRows$2();
for (const row of rows) {
const info = parseTrackRow$2(row);
if (!info) continue;
const rowKey = normalizeKey(info.artist, info.title);
if (rowKey === key) {
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
}
handleNewRows(rows) {
const settings = getSettings();
for (const row of rows) {
const info = parseTrackRow$2(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handlePlayingChanged(row) {
if (!row) {
this.tracker.onTrackStopped();
return;
}
const info = parseTrackRow$2(row);
if (!info) return;
const key = normalizeKey(info.artist, info.title);
this.tracker.onTrackPlaying(key, info.artist, info.title, "yandex", info.platformId);
}
}
function getPlayerApiData() {
const player = document.querySelector("#movie_player");
if (!player?.getVideoData) return null;
const data = player.getVideoData();
const title = (data.title ?? "").trim();
const artist = (data.author ?? "").trim();
const videoId = (data.video_id ?? "").trim();
if (!title || !artist || !videoId) return null;
return { artist, title, platformId: videoId };
}
function parseTrackRow$1(element) {
const titleEl = element.querySelector("yt-formatted-string.title") ?? element.querySelector(".song-title");
const title = (titleEl?.textContent ?? titleEl?.getAttribute("title") ?? "").trim();
let artist = "";
const artistLink = element.querySelector(".byline a") ?? element.querySelector(".secondary-flex-columns yt-formatted-string a") ?? element.querySelector(".flex-column a");
if (artistLink) {
artist = (artistLink.textContent ?? "").trim();
} else {
const bylineEl = element.querySelector(".byline") ?? element.querySelector("yt-formatted-string.flex-column");
if (bylineEl) {
artist = (bylineEl.textContent ?? "").split("•")[0].trim();
}
}
if (!title || !artist) return null;
const watchLink = element.querySelector('a[href*="watch?v="]');
let platformId = "";
if (watchLink) {
try {
const url = new URL(watchLink.href, location.origin);
platformId = url.searchParams.get("v") ?? "";
} catch {
platformId = "";
}
}
if (!platformId) {
try {
platformId = new URL(location.href).searchParams.get("v") ?? "";
} catch {
}
}
if (!platformId) {
platformId = `ytm_${artist}_${title}`;
}
return { artist, title, platformId };
}
function parsePlayerBar() {
const bar = document.querySelector("ytmusic-player-bar");
if (!bar) return null;
const titleEl = bar.querySelector("yt-formatted-string.title");
const title = (titleEl?.textContent ?? titleEl?.getAttribute("title") ?? "").trim();
const bylineLink = bar.querySelector("yt-formatted-string.byline a");
let artist = "";
if (bylineLink) {
artist = (bylineLink.textContent ?? "").trim();
} else {
const bylineEl = bar.querySelector("yt-formatted-string.byline");
if (bylineEl) {
artist = (bylineEl.textContent ?? "").trim();
}
}
if (!title || !artist) return null;
const watchLink = bar.querySelector('a[href*="watch?v="]');
let platformId = "";
if (watchLink) {
try {
const url = new URL(watchLink.href, location.origin);
platformId = url.searchParams.get("v") ?? "";
} catch {
platformId = "";
}
}
if (!platformId) {
try {
const url = new URL(location.href);
platformId = url.searchParams.get("v") ?? "";
} catch {
platformId = "";
}
}
if (!platformId) {
platformId = `ytm_${artist}_${title}`;
}
return { artist, title, platformId };
}
function findAllTrackRows$1(root = document) {
return Array.from(root.querySelectorAll(
"ytmusic-responsive-list-item-renderer, ytmusic-player-queue-item"
));
}
function findPlayingRow$1(root = document) {
const selectedQueue = root.querySelector(
"ytmusic-player-queue-item[selected]"
);
if (selectedQueue) return selectedQueue;
const playingItem = root.querySelector(
'ytmusic-responsive-list-item-renderer[play-button-state="playing"], ytmusic-responsive-list-item-renderer[play-button-state="paused"]'
);
if (playingItem) return playingItem;
return null;
}
function getCurrentTrackInfo() {
const apiData = getPlayerApiData();
if (apiData) return apiData;
const playingRow = findPlayingRow$1();
if (playingRow) {
const rowInfo = parseTrackRow$1(playingRow);
if (rowInfo) return rowInfo;
}
return parsePlayerBar();
}
function hasMusicContent$2() {
return true;
}
class YouTubeObserver {
mutationObserver = null;
playingPollInterval = null;
onNewRows;
onPlayingChanged;
processedRows = new WeakSet();
currentPlayingId = null;
debounceTimer = null;
constructor(onNewRows, onPlayingChanged) {
this.onNewRows = onNewRows;
this.onPlayingChanged = onPlayingChanged;
}
start() {
this.scanExistingRows();
this.startMutationObserver();
this.startPlayingPoll();
}
stop() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
this.mutationObserver = null;
}
if (this.playingPollInterval) {
clearInterval(this.playingPollInterval);
this.playingPollInterval = null;
}
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
scanExistingRows() {
const rows = findAllTrackRows$1();
const newRows = rows.filter((r) => !this.processedRows.has(r));
for (const row of newRows) this.processedRows.add(row);
if (newRows.length > 0) this.onNewRows(newRows);
}
startMutationObserver() {
this.mutationObserver = new MutationObserver(() => {
if (this.debounceTimer) clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.debounceTimer = null;
this.scanExistingRows();
}, 300);
});
this.mutationObserver.observe(document.body, {
childList: true,
subtree: true
});
}
startPlayingPoll() {
this.playingPollInterval = setInterval(() => {
const trackInfo = getCurrentTrackInfo();
const playingId = trackInfo?.platformId ?? null;
if (playingId !== this.currentPlayingId) {
this.currentPlayingId = playingId;
this.onPlayingChanged(playingId !== null ? document.querySelector(
'ytmusic-player-queue-item[selected], ytmusic-responsive-list-item-renderer[play-button-state="playing"], ytmusic-responsive-list-item-renderer[play-button-state="paused"]'
) ?? document.createElement("div") : null);
}
}, 500);
}
}
class YouTubePlatform {
db;
tracker;
observer = null;
constructor(db, tracker) {
this.db = db;
this.tracker = tracker;
}
start() {
this.observer = new YouTubeObserver(
(rows) => this.handleNewRows(rows),
(row) => this.handlePlayingChanged(row)
);
this.observer.start();
}
stop() {
this.observer?.stop();
this.tracker.destroy();
}
rehighlightAll() {
const settings = getSettings();
const rows = findAllTrackRows$1();
for (const row of rows) {
const info = parseTrackRow$1(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
rehighlightKey(key) {
const settings = getSettings();
const count = this.db.getPlayCount(key);
const rows = findAllTrackRows$1();
for (const row of rows) {
const info = parseTrackRow$1(row);
if (!info) continue;
const rowKey = normalizeKey(info.artist, info.title);
if (rowKey === key) {
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
}
handleNewRows(rows) {
const settings = getSettings();
for (const row of rows) {
const info = parseTrackRow$1(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handlePlayingChanged(row) {
if (!row) {
this.tracker.onTrackStopped();
return;
}
const info = getCurrentTrackInfo() ?? parseTrackRow$1(row);
if (!info) return;
const key = normalizeKey(info.artist, info.title);
this.tracker.onTrackPlaying(key, info.artist, info.title, "youtube", info.platformId);
}
}
function parseTrackRow(element) {
const titleLink = element.querySelector(
'a[data-testid="internal-track-link"]'
);
if (!titleLink) return null;
const title = titleLink.textContent?.trim() ?? "";
const artistLinks = element.querySelectorAll('a[href*="/artist/"]');
const artist = Array.from(artistLinks).map((el) => el.textContent?.trim()).filter(Boolean).join(", ");
if (!title || !artist) return null;
const href = titleLink.getAttribute("href") ?? "";
const match = href.match(/\/track\/([a-zA-Z0-9]+)/);
const platformId = match ? match[1] : `sp_${artist}_${title}`;
return { artist, title, platformId };
}
function findAllTrackRows(root = document) {
return Array.from(root.querySelectorAll('[data-testid="tracklist-row"]'));
}
function findPlayingRow(root = document) {
const anim = root.querySelector('[class*="PlayingAnimation"]');
if (anim) {
const row = anim.closest('[data-testid="tracklist-row"]');
if (row) return row;
}
const playBtn = root.querySelector('[data-testid="control-button-playpause"]');
if (playBtn?.getAttribute("aria-label") === "Pause") {
const npInfo = parseNowPlayingBar(root);
if (npInfo) {
const rows = findAllTrackRows(root);
for (const row of rows) {
const info = parseTrackRow(row);
if (info && info.title === npInfo.title && info.artist === npInfo.artist) {
return row;
}
}
}
}
return null;
}
function parseNowPlayingBar(root = document) {
const bar = root.querySelector('[data-testid="now-playing-bar"]');
if (!bar) return null;
const titleLink = bar.querySelector(
'a[data-testid="internal-track-link"], a[data-testid="context-item-link"]'
);
if (!titleLink) return null;
const title = titleLink.textContent?.trim() ?? "";
const artistLinks = bar.querySelectorAll(
'a[href*="/artist/"], a[data-testid="context-item-info-artist"]'
);
const artist = Array.from(artistLinks).map((el) => el.textContent?.trim()).filter(Boolean).join(", ");
if (!title || !artist) return null;
const href = titleLink.getAttribute("href") ?? "";
const match = href.match(/\/(?:track|album)\/([a-zA-Z0-9]+)/);
const platformId = match ? match[1] : `sp_${artist}_${title}`;
return { artist, title, platformId };
}
function hasMusicContent$1(root = document) {
if (findAllTrackRows(root).length > 0) return true;
const bar = root.querySelector('[data-testid="now-playing-bar"]');
if (bar) {
const link = bar.querySelector('a[data-testid="internal-track-link"]');
if (link) return true;
}
return false;
}
class SpotifyObserver {
mutationObserver = null;
playingPollInterval = null;
onNewRows;
onPlayingChanged;
processedRows = new WeakSet();
currentPlayingId = null;
debounceTimer = null;
constructor(onNewRows, onPlayingChanged) {
this.onNewRows = onNewRows;
this.onPlayingChanged = onPlayingChanged;
}
start() {
this.scanExistingRows();
this.startMutationObserver();
this.startPlayingPoll();
}
stop() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
this.mutationObserver = null;
}
if (this.playingPollInterval) {
clearInterval(this.playingPollInterval);
this.playingPollInterval = null;
}
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
scanExistingRows() {
const rows = findAllTrackRows();
const newRows = rows.filter((r) => !this.processedRows.has(r));
for (const row of newRows) this.processedRows.add(row);
if (newRows.length > 0) this.onNewRows(newRows);
}
startMutationObserver() {
this.mutationObserver = new MutationObserver(() => {
if (this.debounceTimer) clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.debounceTimer = null;
this.scanExistingRows();
}, 300);
});
this.mutationObserver.observe(document.body, {
childList: true,
subtree: true
});
}
startPlayingPoll() {
this.playingPollInterval = setInterval(() => {
const playingRow = findPlayingRow();
if (playingRow) {
const link = playingRow.querySelector(
'a[data-testid="internal-track-link"]'
);
const playingId = link?.getAttribute("href") ?? null;
if (playingId !== this.currentPlayingId) {
this.currentPlayingId = playingId;
this.onPlayingChanged(playingRow);
}
return;
}
const nowPlaying = parseNowPlayingBar();
const barId = nowPlaying ? `/track/${nowPlaying.platformId}` : null;
if (barId !== this.currentPlayingId) {
this.currentPlayingId = barId;
if (nowPlaying) {
this.onPlayingChanged(null, true);
} else {
this.onPlayingChanged(null);
}
}
}, 500);
}
}
class SpotifyPlatform {
db;
tracker;
observer = null;
constructor(db, tracker) {
this.db = db;
this.tracker = tracker;
}
start() {
this.observer = new SpotifyObserver(
(rows) => this.handleNewRows(rows),
(row, nowPlayingBar) => this.handlePlayingChanged(row, nowPlayingBar)
);
this.observer.start();
}
stop() {
this.observer?.stop();
this.tracker.destroy();
}
rehighlightAll() {
const settings = getSettings();
const rows = findAllTrackRows();
for (const row of rows) {
const info = parseTrackRow(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
rehighlightKey(key) {
const settings = getSettings();
const count = this.db.getPlayCount(key);
const rows = findAllTrackRows();
for (const row of rows) {
const info = parseTrackRow(row);
if (!info) continue;
const rowKey = normalizeKey(info.artist, info.title);
if (rowKey === key) {
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
}
handleNewRows(rows) {
const settings = getSettings();
for (const row of rows) {
const info = parseTrackRow(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handlePlayingChanged(row, nowPlayingBar) {
if (!row && !nowPlayingBar) {
this.tracker.onTrackStopped();
return;
}
let info;
if (row) {
info = parseTrackRow(row);
} else if (nowPlayingBar) {
info = parseNowPlayingBar();
}
if (!info) return;
const key = normalizeKey(info.artist, info.title);
this.tracker.onTrackPlaying(key, info.artist, info.title, "spotify", info.platformId);
}
}
function parseTrackItem(element) {
const soundTitleEl = element.querySelector(".soundTitle__title");
if (soundTitleEl) {
const title = (soundTitleEl.textContent ?? "").trim();
const artistEl = element.querySelector(".soundTitle__username");
const artist = (artistEl?.textContent ?? "").trim();
if (!title || !artist) return null;
const href = soundTitleEl.getAttribute("href") ?? "";
return { artist, title, platformId: href || `sc_${artist}_${title}` };
}
if (element.classList.contains("compactTrackList__item") || element.classList.contains("systemPlaylistTrackList__item")) {
const links = element.querySelectorAll("a[href]");
let artist = "";
let title = "";
let trackHref = "";
for (const link of links) {
const href = link.getAttribute("href") ?? "";
const clean = href.split("?")[0];
const parts = clean.split("/").filter(Boolean);
if (parts.length === 2 && link.textContent?.trim()) {
title = (link.textContent ?? "").trim();
trackHref = clean;
} else if (parts.length === 1 && link.textContent?.trim()) {
artist = (link.textContent ?? "").trim();
}
}
if (!title || !artist) return null;
return { artist, title, platformId: trackHref || `sc_${artist}_${title}` };
}
return null;
}
function findAllTrackItems(root = document) {
return Array.from(root.querySelectorAll(
".soundTitle__titleContainer, .compactTrackList__item, .systemPlaylistTrackList__item"
));
}
function getCurrentTrackFromPlayer() {
const titleLink = document.querySelector(".playbackSoundBadge__titleLink");
const artistLink = document.querySelector(".playbackSoundBadge__lightLink");
if (!titleLink || !artistLink) return null;
let title = "";
const spans = titleLink.querySelectorAll("span");
for (const span of spans) {
if (!span.classList.contains("sc-visuallyhidden")) {
title = (span.textContent ?? "").trim();
if (title) break;
}
}
if (title.toLowerCase().startsWith("current track:")) {
title = title.replace(/^current track:\s*/i, "").trim();
const half = Math.floor(title.length / 2);
if (half > 0 && title.substring(0, half) === title.substring(half)) {
title = title.substring(0, half);
}
}
let artist = (artistLink.textContent ?? "").trim();
if (!title || !artist) return null;
const href = titleLink.getAttribute("href") ?? "";
const platformId = href || `sc_${artist}_${title}`;
const trackItems = document.querySelectorAll(".soundTitle__titleContainer");
for (const tc of trackItems) {
const tcTitle = tc.querySelector(".soundTitle__title");
if (tcTitle?.getAttribute("href") === href) {
const tcArtist = tc.querySelector(".soundTitle__username");
if (tcArtist) {
artist = (tcArtist.textContent ?? "").trim();
}
break;
}
}
return { artist, title, platformId };
}
function hasMusicContent() {
return findAllTrackItems().length > 0 || !!document.querySelector(".playbackSoundBadge__titleLink");
}
class SoundCloudObserver {
mutationObserver = null;
playingPollInterval = null;
onNewRows;
onPlayingChanged;
processedRows = new WeakSet();
currentPlayingId = null;
debounceTimer = null;
constructor(onNewRows, onPlayingChanged) {
this.onNewRows = onNewRows;
this.onPlayingChanged = onPlayingChanged;
}
start() {
this.scanExistingRows();
this.startMutationObserver();
this.startPlayingPoll();
}
stop() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
this.mutationObserver = null;
}
if (this.playingPollInterval) {
clearInterval(this.playingPollInterval);
this.playingPollInterval = null;
}
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
scanExistingRows() {
const rows = findAllTrackItems();
const newRows = rows.filter((r) => !this.processedRows.has(r));
for (const row of newRows) this.processedRows.add(row);
if (newRows.length > 0) this.onNewRows(newRows);
}
startMutationObserver() {
this.mutationObserver = new MutationObserver(() => {
if (this.debounceTimer) clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.debounceTimer = null;
this.scanExistingRows();
}, 300);
});
this.mutationObserver.observe(document.body, {
childList: true,
subtree: true
});
}
startPlayingPoll() {
this.playingPollInterval = setInterval(() => {
const current = getCurrentTrackFromPlayer();
const currentId = current?.platformId ?? null;
if (currentId !== this.currentPlayingId) {
this.currentPlayingId = currentId;
this.onPlayingChanged(current);
}
}, 500);
}
}
class SoundCloudPlatform {
db;
tracker;
observer = null;
constructor(db, tracker) {
this.db = db;
this.tracker = tracker;
}
start() {
this.observer = new SoundCloudObserver(
(rows) => this.handleNewRows(rows),
(info) => this.handlePlayingChanged(info)
);
this.observer.start();
}
stop() {
this.observer?.stop();
this.tracker.destroy();
}
rehighlightAll() {
const settings = getSettings();
const rows = findAllTrackItems();
for (const row of rows) {
const info = parseTrackItem(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
rehighlightKey(key) {
const settings = getSettings();
const count = this.db.getPlayCount(key);
const rows = findAllTrackItems();
for (const row of rows) {
const info = parseTrackItem(row);
if (!info) continue;
const rowKey = normalizeKey(info.artist, info.title);
if (rowKey === key) {
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
}
handleNewRows(rows) {
const settings = getSettings();
for (const row of rows) {
const info = parseTrackItem(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
const count = this.db.getPlayCount(key);
applyHighlight(row, count, settings.colorFrom, settings.colorTo, settings.steps, settings.maxAlpha);
}
}
handlePlayingChanged(info) {
if (!info) {
this.tracker.onTrackStopped();
return;
}
const key = normalizeKey(info.artist, info.title);
this.tracker.onTrackPlaying(key, info.artist, info.title, "soundcloud", info.platformId);
}
}
try {
if (window.trustedTypes?.createPolicy) {
window.trustedTypes.createPolicy("default", {
createHTML: (s) => s,
createScriptURL: (s) => s,
createScript: (s) => s
});
}
} catch {
}
function detectPlatform(hostname) {
if (hostname === "vk.com" || hostname === "vk.ru") {
return {
platform: "vk",
factory: (db, tracker) => new VKPlatform(db, tracker),
hasMusicContent: hasMusicContent$4
};
}
if (hostname === "music.yandex.ru" || hostname === "music.yandex.com") {
return {
platform: "yandex",
factory: (db, tracker) => new YandexPlatform(db, tracker),
hasMusicContent: hasMusicContent$3
};
}
if (hostname === "music.youtube.com") {
return {
platform: "youtube",
factory: (db, tracker) => new YouTubePlatform(db, tracker),
hasMusicContent: hasMusicContent$2
};
}
if (hostname === "open.spotify.com") {
return {
platform: "spotify",
factory: (db, tracker) => new SpotifyPlatform(db, tracker),
hasMusicContent: hasMusicContent$1
};
}
if (hostname === "soundcloud.com" || hostname === "www.soundcloud.com") {
return {
platform: "soundcloud",
factory: (db, tracker) => new SoundCloudPlatform(db, tracker),
hasMusicContent
};
}
return null;
}
async function main() {
const hostname = window.location.hostname;
const detected = detectPlatform(hostname);
if (!detected) {
return;
}
const db = new TrackDB();
await db.init();
const settings = getSettings();
const tracker = new Tracker(db, settings);
const platform = detected.factory(db, tracker);
platform.start();
injectStyles();
const panel = new Panel(db, detected.platform);
panel.mount();
panel.setVisibilityChecker(() => detected.hasMusicContent());
if (typeof GM_registerMenuCommand === "function") {
GM_registerMenuCommand("Toggle view", () => {
panel.toggleVisibility();
});
}
panel.setOnSettingsChanged((newSettings) => {
tracker.updateSettings(newSettings);
platform.rehighlightAll();
});
panel.setOnImported(() => {
broadcast({ type: "tracks-imported" });
platform.rehighlightAll();
panel.updateStat();
});
tracker.setOnUpdated((key, playCount) => {
broadcast({ type: "track-updated", key, playCount });
platform.rehighlightKey(key);
panel.updateStat();
});
initSync((msg) => {
if (msg.type === "track-updated" && msg.key) {
db.init().then(() => {
const s = getSettings();
if (detected.platform === "vk") {
const rows = findAllAudioRows();
for (const row of rows) {
const info = parseAudioRow(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
if (key === msg.key) {
applyHighlight(row, msg.playCount ?? 0, s.colorFrom, s.colorTo, s.steps);
}
}
} else if (detected.platform === "yandex") {
const rows = findAllTrackRows$2();
for (const row of rows) {
const info = parseTrackRow$2(row);
if (!info) continue;
const key = normalizeKey(info.artist, info.title);
if (key === msg.key) {
applyHighlight(row, msg.playCount ?? 0, s.colorFrom, s.colorTo, s.steps);
}
}
}
panel.updateStat();
});
}
if (msg.type === "tracks-imported" || msg.type === "tracks-cleared") {
db.init().then(() => {
platform.rehighlightAll();
panel.updateStat();
});
}
});
}
main();
})();