diff --git a/background/sync-manager.js b/background/sync-manager.js
index b8f32cce..cf565baa 100644
--- a/background/sync-manager.js
+++ b/background/sync-manager.js
@@ -179,7 +179,7 @@ const syncMan = (() => {
//#region Utils
async function initController() {
- await require(['/vendor/db-to-cloud/db-to-cloud.min']); /* global dbToCloud */
+ await require(['/vendor/db-to-cloud/db-to-cloud']); /* global dbToCloud */
ctrl = dbToCloud.dbToCloud({
onGet: styleUtil.uuid2style,
async onPut(doc) {
diff --git a/background/token-manager.js b/background/token-manager.js
index b5756339..3be95804 100644
--- a/background/token-manager.js
+++ b/background/token-manager.js
@@ -144,7 +144,7 @@ const tokenMan = (() => {
}
async function authUser(keys, name, interactive = false, hooks = null) {
- await require(['/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min']);
+ await require(['/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow']);
/* global webextLaunchWebAuthFlow */
const provider = AUTH[name];
const state = Math.random().toFixed(8).slice(2);
diff --git a/js/meta-parser.js b/js/meta-parser.js
index f153c5d3..49eb26ee 100644
--- a/js/meta-parser.js
+++ b/js/meta-parser.js
@@ -2,7 +2,7 @@
/* exported metaParser */
const metaParser = (() => {
- require(['/vendor/usercss-meta/usercss-meta.min']); /* global usercssMeta */
+ require(['/vendor/usercss-meta/usercss-meta']); /* global usercssMeta */
const {createParser, ParseError} = usercssMeta;
const PREPROCESSORS = new Set(['default', 'uso', 'stylus', 'less']);
const options = {
diff --git a/manage/manage.js b/manage/manage.js
index fcf9e3c2..21ad814e 100644
--- a/manage/manage.js
+++ b/manage/manage.js
@@ -63,7 +63,7 @@ newUI.renderClass();
router.makeToggle('stylus-options', toggleEmbeddedOptions);
$('#injection-order-button').onclick =
router.makeToggle('injection-order', (...args) => InjectionOrder(...args), [
- '/vendor/draggable-list/draggable-list.iife.min.js',
+ '/vendor/draggable-list/draggable-list.iife',
'/injection-order/injection-order.css',
'/injection-order/injection-order', /* global InjectionOrder */
]);
diff --git a/tools/build-vendor.js b/tools/build-vendor.js
index 8303d6dd..8f2ec5e7 100644
--- a/tools/build-vendor.js
+++ b/tools/build-vendor.js
@@ -53,16 +53,16 @@ const files = {
'dist/stylus-renderer.min.js',
],
'usercss-meta': [
- 'dist/usercss-meta.min.js',
+ 'dist/usercss-meta.js',
],
'db-to-cloud': [
- 'dist/db-to-cloud.min.js',
+ 'dist/db-to-cloud.js',
],
'webext-launch-web-auth-flow': [
- 'dist/webext-launch-web-auth-flow.min.js',
+ 'dist/webext-launch-web-auth-flow.js',
],
'@eight04/draggable-list': [
- 'dist/draggable-list.iife.min.js',
+ 'dist/draggable-list.iife.js',
],
};
@@ -101,10 +101,18 @@ async function buildFiles(pkg, flatPkg, patterns) {
throw new Error(`Pattern ${src} matches no files`);
}
for (const file of files) {
- fse.copySync(file, dest
+ const destPath = dest
? `vendor/${flatPkg}/${dest}`
- : `vendor/${path.relative('node_modules', file).replace(pkg + '/', flatPkg + '/')}`);
- copied += `* ${reportFile(pkg, file, dest)}\n`;
+ : `vendor/${path.relative('node_modules', file).replace(pkg + '/', flatPkg + '/')}`;
+ const txt = file.endsWith('.js') && fs.readFileSync(file, 'utf8');
+ const txt2 = txt && txt.replace(/\n\/\/# sourceMappingURL=.*\s*$/, '\n');
+ const hasSM = txt && txt !== txt2;
+ if (hasSM) {
+ fse.outputFileSync(destPath, txt2);
+ } else {
+ fse.copySync(file, destPath);
+ }
+ copied += `* ${reportFile(pkg, file, dest)}${hasSM ? ' (removed sourceMappingURL)' : ''}\n`;
}
}
}
diff --git a/vendor/db-to-cloud/README.md b/vendor/db-to-cloud/README.md
index 37c2ab14..df5bfb5f 100644
--- a/vendor/db-to-cloud/README.md
+++ b/vendor/db-to-cloud/README.md
@@ -1,4 +1,4 @@
## db-to-cloud v0.7.0
Files copied from NPM (node_modules):
-* db-to-cloud.min.js: dist/*
+* db-to-cloud.js: dist/* (removed sourceMappingURL)
diff --git a/vendor/db-to-cloud/db-to-cloud.js b/vendor/db-to-cloud/db-to-cloud.js
new file mode 100644
index 00000000..1c8451b4
--- /dev/null
+++ b/vendor/db-to-cloud/db-to-cloud.js
@@ -0,0 +1,2262 @@
+var dbToCloud = (function (exports) {
+ 'use strict';
+
+ function ownKeys(object, enumerableOnly) {
+ var keys = Object.keys(object);
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(object);
+
+ if (enumerableOnly) {
+ symbols = symbols.filter(function (sym) {
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+ });
+ }
+
+ keys.push.apply(keys, symbols);
+ }
+
+ return keys;
+ }
+
+ function _objectSpread2(target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i] != null ? arguments[i] : {};
+
+ if (i % 2) {
+ ownKeys(Object(source), true).forEach(function (key) {
+ _defineProperty(target, key, source[key]);
+ });
+ } else if (Object.getOwnPropertyDescriptors) {
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
+ } else {
+ ownKeys(Object(source)).forEach(function (key) {
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
+ });
+ }
+ }
+
+ return target;
+ }
+
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+ try {
+ var info = gen[key](arg);
+ var value = info.value;
+ } catch (error) {
+ reject(error);
+ return;
+ }
+
+ if (info.done) {
+ resolve(value);
+ } else {
+ Promise.resolve(value).then(_next, _throw);
+ }
+ }
+
+ function _asyncToGenerator(fn) {
+ return function () {
+ var self = this,
+ args = arguments;
+ return new Promise(function (resolve, reject) {
+ var gen = fn.apply(self, args);
+
+ function _next(value) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+ }
+
+ function _throw(err) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+ }
+
+ _next(undefined);
+ });
+ };
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function _objectWithoutPropertiesLoose(source, excluded) {
+ if (source == null) return {};
+ var target = {};
+ var sourceKeys = Object.keys(source);
+ var key, i;
+
+ for (i = 0; i < sourceKeys.length; i++) {
+ key = sourceKeys[i];
+ if (excluded.indexOf(key) >= 0) continue;
+ target[key] = source[key];
+ }
+
+ return target;
+ }
+
+ function _objectWithoutProperties(source, excluded) {
+ if (source == null) return {};
+
+ var target = _objectWithoutPropertiesLoose(source, excluded);
+
+ var key, i;
+
+ if (Object.getOwnPropertySymbols) {
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
+
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
+ key = sourceSymbolKeys[i];
+ if (excluded.indexOf(key) >= 0) continue;
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
+ target[key] = source[key];
+ }
+ }
+
+ return target;
+ }
+
+ function _slicedToArray(arr, i) {
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
+ }
+
+ function _arrayWithHoles(arr) {
+ if (Array.isArray(arr)) return arr;
+ }
+
+ function _iterableToArrayLimit(arr, i) {
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
+
+ if (_i == null) return;
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+
+ var _s, _e;
+
+ try {
+ for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
+ _arr.push(_s.value);
+
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i["return"] != null) _i["return"]();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+
+ return _arr;
+ }
+
+ function _unsupportedIterableToArray(o, minLen) {
+ if (!o) return;
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+ var n = Object.prototype.toString.call(o).slice(8, -1);
+ if (n === "Object" && o.constructor) n = o.constructor.name;
+ if (n === "Map" || n === "Set") return Array.from(o);
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
+ }
+
+ function _arrayLikeToArray(arr, len) {
+ if (len == null || len > arr.length) len = arr.length;
+
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+
+ return arr2;
+ }
+
+ function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+
+ function _createForOfIteratorHelper(o, allowArrayLike) {
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
+
+ if (!it) {
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
+ if (it) o = it;
+ var i = 0;
+
+ var F = function () {};
+
+ return {
+ s: F,
+ n: function () {
+ if (i >= o.length) return {
+ done: true
+ };
+ return {
+ done: false,
+ value: o[i++]
+ };
+ },
+ e: function (e) {
+ throw e;
+ },
+ f: F
+ };
+ }
+
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+
+ var normalCompletion = true,
+ didErr = false,
+ err;
+ return {
+ s: function () {
+ it = it.call(o);
+ },
+ n: function () {
+ var step = it.next();
+ normalCompletion = step.done;
+ return step;
+ },
+ e: function (e) {
+ didErr = true;
+ err = e;
+ },
+ f: function () {
+ try {
+ if (!normalCompletion && it.return != null) it.return();
+ } finally {
+ if (didErr) throw err;
+ }
+ }
+ };
+ }
+
+ function createLock({
+ maxActiveReader = Infinity
+ } = {}) {
+ let firstTask;
+ let lastTask;
+ let activeReader = 0;
+ const self = {
+ read: fn => que(fn, false),
+ write: fn => que(fn, true),
+ length: 0
+ };
+ return self;
+
+ function que(fn, block) {
+ const task = createTask({
+ fn,
+ block
+ });
+
+ if (!lastTask) {
+ firstTask = lastTask = task;
+ } else {
+ lastTask.next = task;
+ task.prev = lastTask;
+ lastTask = task;
+
+ if (!firstTask) {
+ firstTask = lastTask;
+ }
+ }
+
+ self.length++;
+ deque();
+ return task.q.promise;
+ }
+
+ function defer() {
+ const o = {};
+ o.promise = new Promise((resolve, reject) => {
+ o.resolve = resolve;
+ o.reject = reject;
+ });
+ return o;
+ }
+
+ function createTask({
+ fn,
+ block = false,
+ prev,
+ next,
+ q = defer(),
+ q2 = fn.length ? defer() : null
+ }) {
+ return {
+ fn,
+ block,
+ prev,
+ next,
+ q,
+ q2
+ };
+ }
+
+ function deque() {
+ const task = firstTask;
+
+ if (!task || task.block && task.prev || task.prev && task.prev.block || activeReader >= maxActiveReader) {
+ return;
+ }
+
+ if (!task.block) {
+ activeReader++;
+ }
+
+ firstTask = task.next;
+ let result;
+
+ try {
+ result = task.fn(task.q2 && task.q2.resolve);
+ } catch (err) {
+ task.q.reject(err); // auto release with sync error
+ // q2 is useless in this case
+
+ onDone();
+ return;
+ }
+
+ if (task.q2) {
+ task.q2.promise.then(_onDone);
+ }
+
+ if (result && result.then) {
+ const pending = result.then(task.q.resolve, task.q.reject);
+
+ if (!task.q2) {
+ pending.then(onDone);
+ }
+ } else {
+ task.q.resolve(result);
+
+ if (!task.q2) {
+ // it's a sync function and you don't want to release it manually, why
+ // do you need a lock?
+ onDone();
+ return;
+ }
+ }
+
+ deque();
+
+ function onDone() {
+ _onDone();
+ }
+
+ function _onDone(afterDone) {
+ if (task.prev) {
+ task.prev.next = task.next;
+ }
+
+ if (task.next) {
+ task.next.prev = task.prev;
+ }
+
+ if (lastTask === task) {
+ lastTask = task.prev;
+ }
+
+ if (!task.block) {
+ activeReader--;
+ }
+
+ self.length--;
+
+ if (afterDone) {
+ afterDone();
+ }
+
+ deque();
+ }
+ }
+ }
+
+ class LockError extends Error {
+ constructor(expire) {
+ super("The database is locked. Will expire at ".concat(new Date(expire).toLocaleString()));
+ this.expire = expire;
+ this.name = "LockError";
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, LockError);
+ }
+ }
+
+ }
+
+ function debounced(fn) {
+ let timer = 0;
+ let q;
+ return () => {
+ if (timer) {
+ clearTimeout(timer);
+ }
+
+ timer = setTimeout(run);
+
+ if (!q) {
+ q = defer();
+ }
+
+ return q.promise;
+ };
+
+ function run() {
+ Promise.resolve(fn()).then(q.resolve, q.reject);
+ timer = 0;
+ q = null;
+ }
+
+ function defer() {
+ const o = {};
+ o.promise = new Promise((resolve, reject) => {
+ o.resolve = resolve;
+ o.reject = reject;
+ });
+ return o;
+ }
+ }
+
+ function delay(time) {
+ return new Promise(resolve => setTimeout(resolve, time));
+ }
+
+ function buildDrive(_drive) {
+ const drive = Object.create(_drive);
+
+ drive.get = /*#__PURE__*/function () {
+ var _ref = _asyncToGenerator(function* (path) {
+ return JSON.parse(yield _drive.get(path));
+ });
+
+ return function (_x) {
+ return _ref.apply(this, arguments);
+ };
+ }();
+
+ drive.put = /*#__PURE__*/function () {
+ var _ref2 = _asyncToGenerator(function* (path, data) {
+ return yield _drive.put(path, JSON.stringify(data));
+ });
+
+ return function (_x2, _x3) {
+ return _ref2.apply(this, arguments);
+ };
+ }();
+
+ drive.post = /*#__PURE__*/function () {
+ var _ref3 = _asyncToGenerator(function* (path, data) {
+ return yield _drive.post(path, JSON.stringify(data));
+ });
+
+ return function (_x4, _x5) {
+ return _ref3.apply(this, arguments);
+ };
+ }();
+
+ drive.isInit = false;
+
+ if (!drive.acquireLock) {
+ drive.acquireLock = acquireLock;
+ drive.releaseLock = releaseLock;
+ }
+
+ if (!drive.getMeta) {
+ drive.getMeta = getMeta;
+ drive.putMeta = putMeta;
+ }
+
+ if (!drive.peekChanges) {
+ drive.peekChanges = peekChanges;
+ }
+
+ return drive;
+
+ function acquireLock(_x6) {
+ return _acquireLock.apply(this, arguments);
+ }
+
+ function _acquireLock() {
+ _acquireLock = _asyncToGenerator(function* (expire) {
+ try {
+ yield this.post("lock.json", {
+ expire: Date.now() + expire * 60 * 1000
+ });
+ } catch (err) {
+ if (err.code !== "EEXIST") {
+ throw err;
+ }
+
+ const data = yield this.get("lock.json");
+
+ if (Date.now() > data.expire) {
+ // FIXME: this may delete a different lock created by other instances
+ yield this.delete("lock.json");
+ throw new Error("Found expired lock, please try again");
+ }
+
+ throw new LockError(data.expire);
+ }
+ });
+ return _acquireLock.apply(this, arguments);
+ }
+
+ function releaseLock() {
+ return _releaseLock.apply(this, arguments);
+ }
+
+ function _releaseLock() {
+ _releaseLock = _asyncToGenerator(function* () {
+ yield this.delete("lock.json");
+ });
+ return _releaseLock.apply(this, arguments);
+ }
+
+ function getMeta() {
+ return _getMeta.apply(this, arguments);
+ }
+
+ function _getMeta() {
+ _getMeta = _asyncToGenerator(function* () {
+ try {
+ return yield this.get("meta.json");
+ } catch (err) {
+ if (err.code === "ENOENT" || err.code === 404) {
+ return {};
+ }
+
+ throw err;
+ }
+ });
+ return _getMeta.apply(this, arguments);
+ }
+
+ function putMeta(_x7) {
+ return _putMeta.apply(this, arguments);
+ }
+
+ function _putMeta() {
+ _putMeta = _asyncToGenerator(function* (data) {
+ yield this.put("meta.json", data);
+ });
+ return _putMeta.apply(this, arguments);
+ }
+
+ function peekChanges(_x8) {
+ return _peekChanges.apply(this, arguments);
+ }
+
+ function _peekChanges() {
+ _peekChanges = _asyncToGenerator(function* (oldMeta) {
+ const newMeta = yield this.getMeta();
+ return newMeta.lastChange !== oldMeta.lastChange;
+ });
+ return _peekChanges.apply(this, arguments);
+ }
+ }
+
+ function dbToCloud({
+ onGet,
+ onPut,
+ onDelete,
+ onFirstSync,
+ onWarn = console.error,
+ onProgress,
+ compareRevision,
+ getState,
+ setState,
+ lockExpire = 60,
+ retryMaxAttempts = 5,
+ retryExp = 1.5,
+ retryDelay = 10
+ }) {
+ let _drive2;
+
+ let state;
+ let meta;
+ const changeCache = new Map();
+ const saveState = debounced(() => setState(_drive2, state));
+ const revisionCache = new Map();
+ const lock = createLock();
+ return {
+ use,
+ init,
+ uninit,
+ put,
+ delete: delete_,
+ syncNow,
+ drive: () => _drive2,
+ isInit: () => Boolean(state && state.enabled)
+ };
+
+ function use(newDrive) {
+ _drive2 = buildDrive(newDrive);
+ }
+
+ function init() {
+ return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
+ if (state && state.enabled) {
+ return;
+ }
+
+ if (!_drive2) {
+ throw new Error("cloud drive is undefined");
+ }
+
+ state = (yield getState(_drive2)) || {};
+ state.enabled = true;
+
+ if (!state.queue) {
+ state.queue = [];
+ }
+ }));
+ }
+
+ function uninit() {
+ return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
+ if (!state || !state.enabled) {
+ return;
+ }
+
+ state = meta = null;
+ changeCache.clear();
+ revisionCache.clear();
+
+ if (_drive2.uninit && _drive2.isInit) {
+ yield _drive2.uninit();
+ _drive2.isInit = false;
+ }
+
+ yield saveState();
+ }));
+ }
+
+ function syncPull() {
+ return _syncPull.apply(this, arguments);
+ }
+
+ function _syncPull() {
+ _syncPull = _asyncToGenerator(function* () {
+ meta = yield _drive2.getMeta();
+
+ if (!meta.lastChange || meta.lastChange === state.lastChange) {
+ // nothing changes
+ return;
+ }
+
+ let changes = [];
+
+ if (!state.lastChange) {
+ // pull everything
+ changes = (yield _drive2.list("docs")).map(name => ({
+ action: 'put',
+ _id: name.slice(0, -5)
+ }));
+ } else {
+ const end = Math.floor((meta.lastChange - 1) / 100); // inclusive end
+
+ let i = Math.floor(state.lastChange / 100);
+
+ while (i <= end) {
+ const newChanges = yield _drive2.get("changes/".concat(i, ".json"));
+ changeCache.set(i, newChanges);
+ changes = changes.concat(newChanges);
+ i++;
+ }
+
+ changes = changes.slice(state.lastChange % 100);
+ } // merge changes
+
+
+ const idx = new Map();
+
+ var _iterator = _createForOfIteratorHelper(changes),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ const change = _step.value;
+ idx.set(change._id, change);
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+
+ let loaded = 0;
+
+ var _iterator2 = _createForOfIteratorHelper(idx),
+ _step2;
+
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ const _step2$value = _slicedToArray(_step2.value, 2),
+ id = _step2$value[0],
+ change = _step2$value[1];
+
+ let doc, _rev;
+
+ if (onProgress) {
+ onProgress({
+ phase: 'pull',
+ total: idx.size,
+ loaded,
+ change
+ });
+ }
+
+ if (change.action === "delete") {
+ yield onDelete(id, change._rev);
+ } else if (change.action === "put") {
+ try {
+ var _yield$_drive2$get = yield _drive2.get("docs/".concat(id, ".json"));
+
+ doc = _yield$_drive2$get.doc;
+ _rev = _yield$_drive2$get._rev;
+ } catch (err) {
+ if (err.code === "ENOENT" || err.code === 404) {
+ onWarn("Cannot find ".concat(id, ". Is it deleted without updating the history?"));
+ loaded++;
+ continue;
+ }
+
+ throw err;
+ }
+
+ yield onPut(doc);
+ } // record the remote revision
+
+
+ const rev = change._rev || _rev;
+
+ if (rev) {
+ revisionCache.set(id, rev);
+ }
+
+ loaded++;
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+
+ state.lastChange = meta.lastChange;
+ yield saveState();
+ });
+ return _syncPull.apply(this, arguments);
+ }
+
+ function syncPush() {
+ return _syncPush.apply(this, arguments);
+ }
+
+ function _syncPush() {
+ _syncPush = _asyncToGenerator(function* () {
+ if (!state.queue.length) {
+ // nothing to push
+ return;
+ } // snapshot
+
+
+ const changes = state.queue.slice(); // merge changes
+
+ const idx = new Map();
+
+ var _iterator3 = _createForOfIteratorHelper(changes),
+ _step3;
+
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ const change = _step3.value;
+ idx.set(change._id, change);
+ } // drop outdated change
+
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
+
+ const newChanges = [];
+
+ var _iterator4 = _createForOfIteratorHelper(idx.values()),
+ _step4;
+
+ try {
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
+ const change = _step4.value;
+ // FIXME: is it safe to assume that the local doc is newer when
+ // remoteRev is undefined?
+ const remoteRev = revisionCache.get(change._id);
+
+ if (remoteRev !== undefined && compareRevision(change._rev, remoteRev) <= 0) {
+ continue;
+ }
+
+ newChanges.push(change);
+ } // FIXME: there should be no need to push data when !newChanges.length
+ // start pushing
+
+ } catch (err) {
+ _iterator4.e(err);
+ } finally {
+ _iterator4.f();
+ }
+
+ let loaded = 0;
+
+ for (var _i = 0, _newChanges = newChanges; _i < _newChanges.length; _i++) {
+ const change = _newChanges[_i];
+
+ if (onProgress) {
+ onProgress({
+ phase: 'push',
+ loaded,
+ total: newChanges.length,
+ change
+ });
+ }
+
+ if (change.action === "delete") {
+ yield _drive2.delete("docs/".concat(change._id, ".json"));
+ } else if (change.action === "put") {
+ const doc = yield onGet(change._id, change._rev);
+ yield _drive2.put("docs/".concat(change._id, ".json"), {
+ doc,
+ _rev: change._rev
+ });
+ }
+
+ revisionCache.set(change._id, change._rev);
+ loaded++;
+ } // push changes
+
+
+ let lastChanges;
+ let index; // meta is already pulled in syncPull
+
+ if (meta.lastChange) {
+ index = Math.floor(meta.lastChange / 100);
+ const len = meta.lastChange % 100;
+ lastChanges = len ? changeCache.get(index) || (yield _drive2.get("changes/".concat(index, ".json"))) : []; // it is possible that JSON data contains more records defined by
+ // meta.lastChange
+
+ lastChanges = lastChanges.slice(0, len).concat(newChanges);
+ } else {
+ // first sync
+ index = 0;
+ lastChanges = newChanges;
+ }
+
+ for (let i = 0; i * 100 < lastChanges.length; i++) {
+ const window = lastChanges.slice(i * 100, (i + 1) * 100);
+ yield _drive2.put("changes/".concat(index + i, ".json"), window);
+ changeCache.set(index + i, window);
+ }
+
+ meta.lastChange = (meta.lastChange || 0) + newChanges.length;
+ yield _drive2.putMeta(meta);
+ state.queue = state.queue.slice(changes.length);
+ state.lastChange = meta.lastChange;
+ yield saveState();
+ });
+ return _syncPush.apply(this, arguments);
+ }
+
+ function sync() {
+ return _sync.apply(this, arguments);
+ }
+
+ function _sync() {
+ _sync = _asyncToGenerator(function* () {
+ let tried = 0;
+ let wait = retryDelay;
+ let lastErr;
+
+ while (true) {
+ // eslint-disable-line no-constant-condition
+ try {
+ yield _drive2.acquireLock(lockExpire);
+ break;
+ } catch (err) {
+ if (err.name !== "LockError") {
+ throw err;
+ }
+
+ lastErr = err;
+ }
+
+ tried++;
+
+ if (tried >= retryMaxAttempts) {
+ throw lastErr;
+ }
+
+ yield delay(wait * 1000);
+ wait *= retryExp;
+ }
+
+ try {
+ yield syncPull();
+ yield syncPush();
+ } finally {
+ yield _drive2.releaseLock();
+ }
+ });
+ return _sync.apply(this, arguments);
+ }
+
+ function syncNow(peek) {
+ return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
+ if (!state || !state.enabled) {
+ throw new Error("Cannot sync now, the sync is not enabled");
+ }
+
+ if (_drive2.init && !_drive2.isInit) {
+ yield _drive2.init();
+ _drive2.isInit = true;
+ }
+
+ if (state.lastChange == null) {
+ yield onFirstSync();
+ }
+
+ yield _syncNow(peek);
+ }));
+ }
+
+ function _syncNow() {
+ return _syncNow2.apply(this, arguments);
+ }
+
+ function _syncNow2() {
+ _syncNow2 = _asyncToGenerator(function* (peek = true) {
+ if (onProgress) {
+ onProgress({
+ phase: 'start'
+ });
+ }
+
+ try {
+ if (!state.queue.length && peek && meta) {
+ const changed = yield _drive2.peekChanges(meta);
+
+ if (!changed) {
+ return;
+ }
+ }
+
+ yield sync();
+ } finally {
+ if (onProgress) {
+ onProgress({
+ phase: 'end'
+ });
+ }
+ }
+ });
+ return _syncNow2.apply(this, arguments);
+ }
+
+ function put(_id, _rev) {
+ if (!state || !state.enabled) {
+ return;
+ }
+
+ state.queue.push({
+ _id,
+ _rev,
+ action: "put"
+ });
+ saveState();
+ }
+
+ function delete_(_id, _rev) {
+ if (!state || !state.enabled) {
+ return;
+ }
+
+ state.queue.push({
+ _id,
+ _rev,
+ action: "delete"
+ });
+ saveState();
+ }
+ }
+
+ var empty = (() => {});
+
+ function percentToByte(p) {
+ return String.fromCharCode(parseInt(p.slice(1), 16));
+ }
+
+ function encode(str) {
+ return btoa(encodeURIComponent(str).replace(/%[0-9A-F]{2}/g, percentToByte));
+ }
+
+ function byteToPercent(b) {
+ return "%".concat("00".concat(b.charCodeAt(0).toString(16)).slice(-2));
+ }
+
+ function decode(str) {
+ return decodeURIComponent(Array.from(atob(str), byteToPercent).join(""));
+ }
+
+ const _excluded$2 = ["path", "contentType", "headers", "format", "raw"];
+
+ class RequestError extends Error {
+ constructor(message, origin, code = origin && origin.status) {
+ super(message);
+ this.code = code;
+ this.origin = origin;
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, RequestError);
+ }
+ }
+
+ }
+
+ function createRequest({
+ fetch,
+ cooldown = 0,
+ getAccessToken,
+ username,
+ password
+ }) {
+ const lock = createLock();
+ const basicAuth = username || password ? "Basic ".concat(encode("".concat(username, ":").concat(password))) : null;
+ return args => {
+ return lock.write( /*#__PURE__*/function () {
+ var _ref = _asyncToGenerator(function* (done) {
+ try {
+ return yield doRequest(args);
+ } finally {
+ if (!cooldown || !args.method || args.method === "GET") {
+ done();
+ } else {
+ setTimeout(done, cooldown);
+ }
+ }
+ });
+
+ return function (_x) {
+ return _ref.apply(this, arguments);
+ };
+ }());
+ };
+
+ function doRequest(_x2) {
+ return _doRequest.apply(this, arguments);
+ }
+
+ function _doRequest() {
+ _doRequest = _asyncToGenerator(function* (_ref2) {
+ let path = _ref2.path,
+ contentType = _ref2.contentType,
+ _headers = _ref2.headers,
+ format = _ref2.format,
+ _ref2$raw = _ref2.raw,
+ raw = _ref2$raw === void 0 ? false : _ref2$raw,
+ args = _objectWithoutProperties(_ref2, _excluded$2);
+
+ const headers = {};
+
+ if (getAccessToken) {
+ headers["Authorization"] = "Bearer ".concat(yield getAccessToken());
+ }
+
+ if (basicAuth) {
+ headers["Authorization"] = basicAuth;
+ }
+
+ if (contentType) {
+ headers["Content-Type"] = contentType;
+ }
+
+ Object.assign(headers, _headers);
+
+ while (true) {
+ // eslint-disable-line no-constant-condition
+ // console.log("req", path, args, headers);
+ const res = yield fetch(path, _objectSpread2({
+ headers
+ }, args)); // console.log("res", path, args, res.status, headers);
+
+ if (!res.ok) {
+ const retry = res.headers.get("Retry-After");
+
+ if (retry) {
+ const time = Number(retry);
+
+ if (time) {
+ yield delay(time * 1000);
+ continue;
+ }
+ }
+
+ const text = yield res.text();
+ throw new RequestError("failed to fetch [".concat(res.status, "]: ").concat(text), res);
+ }
+
+ if (raw) {
+ return res;
+ }
+
+ if (format) {
+ return yield res[format]();
+ }
+
+ const resContentType = res.headers.get("Content-Type");
+
+ if (/application\/json/.test(resContentType)) {
+ return yield res.json();
+ }
+
+ return yield res.text();
+ }
+ });
+ return _doRequest.apply(this, arguments);
+ }
+ }
+
+ function createDrive$4({
+ userAgent = "db-to-cloud",
+ owner,
+ repo,
+ getAccessToken,
+ fetch = (typeof self !== "undefined" ? self : global).fetch
+ }) {
+ const request = createRequest({
+ fetch,
+ getAccessToken,
+ cooldown: 1000
+ });
+ const shaCache = new Map();
+ return {
+ name: "github",
+ get,
+ put,
+ post,
+ delete: delete_,
+ list,
+ shaCache
+ };
+
+ function requestAPI(args) {
+ if (!args.headers) {
+ args.headers = {};
+ }
+
+ if (!args.headers["User-Agent"]) {
+ args.headers["User-Agent"] = userAgent;
+ }
+
+ if (!args.headers["Accept"]) {
+ args.headers["Accept"] = "application/vnd.github.v3+json";
+ }
+
+ args.path = "https://api.github.com".concat(args.path);
+ return request(args);
+ }
+
+ function list(_x) {
+ return _list.apply(this, arguments);
+ }
+
+ function _list() {
+ _list = _asyncToGenerator(function* (file) {
+ // FIXME: This API has an upper limit of 1,000 files for a directory. If you need to retrieve more files, use the Git Trees API.
+ const result = yield requestAPI({
+ path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file)
+ });
+ const names = [];
+
+ var _iterator = _createForOfIteratorHelper(result),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ const item = _step.value;
+ names.push(item.name);
+ shaCache.set(item.path, item.sha);
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+
+ return names;
+ });
+ return _list.apply(this, arguments);
+ }
+
+ function get(_x2) {
+ return _get.apply(this, arguments);
+ }
+
+ function _get() {
+ _get = _asyncToGenerator(function* (file) {
+ // FIXME: This API supports files up to 1 megabyte in size.
+ const result = yield requestAPI({
+ path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file)
+ });
+ shaCache.set(result.path, result.sha);
+ return decode(result.content);
+ });
+ return _get.apply(this, arguments);
+ }
+
+ function put(_x3, _x4) {
+ return _put.apply(this, arguments);
+ }
+
+ function _put() {
+ _put = _asyncToGenerator(function* (file, data, overwrite = true) {
+ const params = {
+ message: "",
+ content: encode(data)
+ };
+
+ if (overwrite && shaCache.has(file)) {
+ params.sha = shaCache.get(file);
+ }
+
+ const args = {
+ method: "PUT",
+ path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file),
+ contentType: "application/json",
+ body: JSON.stringify(params)
+ };
+ let retried = false;
+ let result;
+
+ while (!result) {
+ try {
+ result = yield requestAPI(args);
+ } catch (err) {
+ if (err.code !== 422 || !err.message.includes("\\\"sha\\\" wasn't supplied")) {
+ throw err;
+ }
+
+ if (!overwrite || retried) {
+ err.code = "EEXIST";
+ throw err;
+ }
+
+ yield get(file);
+ }
+
+ retried = true;
+ }
+
+ shaCache.set(file, result.content.sha);
+ });
+ return _put.apply(this, arguments);
+ }
+
+ function post(file, data) {
+ return put(file, data, false);
+ }
+
+ function delete_(_x5) {
+ return _delete_.apply(this, arguments);
+ }
+
+ function _delete_() {
+ _delete_ = _asyncToGenerator(function* (file) {
+ try {
+ let sha = shaCache.get(file);
+
+ if (!sha) {
+ yield get(file);
+ sha = shaCache.get(file);
+ }
+
+ yield requestAPI({
+ method: "DELETE",
+ path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file),
+ body: JSON.stringify({
+ message: "",
+ sha
+ })
+ });
+ } catch (err) {
+ if (err.code === 404) {
+ return;
+ } // FIXME: do we have to handle 422 errors?
+
+
+ throw err;
+ }
+ });
+ return _delete_.apply(this, arguments);
+ }
+ }
+
+ const _excluded$1 = ["path", "body"];
+
+ function createDrive$3({
+ getAccessToken,
+ fetch = (typeof self !== "undefined" ? self : global).fetch
+ }) {
+ const request = createRequest({
+ fetch,
+ getAccessToken
+ });
+ return {
+ name: "dropbox",
+ get,
+ put,
+ post,
+ delete: delete_,
+ list
+ };
+
+ function requestRPC(_ref) {
+ let path = _ref.path,
+ body = _ref.body,
+ args = _objectWithoutProperties(_ref, _excluded$1);
+
+ return request(_objectSpread2({
+ method: "POST",
+ path: "https://api.dropboxapi.com/2/".concat(path),
+ contentType: "application/json",
+ body: JSON.stringify(body)
+ }, args));
+ }
+
+ function list(_x) {
+ return _list.apply(this, arguments);
+ }
+
+ function _list() {
+ _list = _asyncToGenerator(function* (file) {
+ const names = [];
+ let result = yield requestRPC({
+ path: "files/list_folder",
+ body: {
+ path: "/".concat(file)
+ }
+ });
+
+ var _iterator = _createForOfIteratorHelper(result.entries),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ const entry = _step.value;
+ names.push(entry.name);
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+
+ if (!result.has_more) {
+ return names;
+ }
+
+ while (result.has_more) {
+ result = yield requestRPC({
+ path: "files/list_folder/continue",
+ body: {
+ cursor: result.cursor
+ }
+ });
+
+ var _iterator2 = _createForOfIteratorHelper(result.entries),
+ _step2;
+
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ const entry = _step2.value;
+ names.push(entry.name);
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+ }
+
+ return names;
+ });
+ return _list.apply(this, arguments);
+ }
+
+ function stringifyParams(obj) {
+ const params = new URLSearchParams();
+ params.set("arg", JSON.stringify(obj));
+ return params.toString();
+ }
+
+ function get(_x2) {
+ return _get.apply(this, arguments);
+ }
+
+ function _get() {
+ _get = _asyncToGenerator(function* (file) {
+ const params = {
+ path: "/".concat(file)
+ };
+
+ try {
+ return yield request({
+ path: "https://content.dropboxapi.com/2/files/download?".concat(stringifyParams(params)),
+ format: "text"
+ });
+ } catch (err) {
+ if (err.code === 409 && err.message.includes("not_found")) {
+ err.code = "ENOENT";
+ }
+
+ throw err;
+ }
+ });
+ return _get.apply(this, arguments);
+ }
+
+ function put(_x3, _x4) {
+ return _put.apply(this, arguments);
+ }
+
+ function _put() {
+ _put = _asyncToGenerator(function* (file, data, mode = "overwrite") {
+ const params = {
+ path: "/".concat(file),
+ mode,
+ autorename: false,
+ mute: true
+ };
+ yield request({
+ path: "https://content.dropboxapi.com/2/files/upload?".concat(stringifyParams(params)),
+ method: "POST",
+ contentType: "application/octet-stream",
+ body: data
+ });
+ });
+ return _put.apply(this, arguments);
+ }
+
+ function post(_x5, _x6) {
+ return _post.apply(this, arguments);
+ }
+
+ function _post() {
+ _post = _asyncToGenerator(function* (file, data) {
+ try {
+ return yield put(file, data, "add");
+ } catch (err) {
+ if (err.code === 409 && err.message.includes("conflict")) {
+ err.code = "EEXIST";
+ }
+
+ throw err;
+ }
+ });
+ return _post.apply(this, arguments);
+ }
+
+ function delete_(_x7) {
+ return _delete_.apply(this, arguments);
+ }
+
+ function _delete_() {
+ _delete_ = _asyncToGenerator(function* (file) {
+ try {
+ yield requestRPC({
+ path: "files/delete_v2",
+ body: {
+ path: "/".concat(file)
+ }
+ });
+ } catch (err) {
+ if (err.code === 409 && err.message.includes("not_found")) {
+ return;
+ }
+
+ throw err;
+ }
+ });
+ return _delete_.apply(this, arguments);
+ }
+ }
+
+ function createDrive$2({
+ getAccessToken,
+ fetch = (typeof self !== "undefined" ? self : global).fetch
+ }) {
+ const request = createRequest({
+ fetch,
+ getAccessToken
+ });
+ return {
+ name: "onedrive",
+ get,
+ put,
+ post,
+ delete: delete_,
+ list
+ };
+
+ function query(_x) {
+ return _query.apply(this, arguments);
+ }
+
+ function _query() {
+ _query = _asyncToGenerator(function* (args) {
+ args.path = "https://graph.microsoft.com/v1.0/me/drive/special/approot".concat(args.path);
+ return yield request(args);
+ });
+ return _query.apply(this, arguments);
+ }
+
+ function list(_x2) {
+ return _list.apply(this, arguments);
+ }
+
+ function _list() {
+ _list = _asyncToGenerator(function* (file) {
+ if (file) {
+ file = ":/".concat(file, ":");
+ }
+
+ let result = yield query({
+ path: "".concat(file, "/children?select=name")
+ });
+ let files = result.value.map(i => i.name);
+
+ while (result["@odata.nextLink"]) {
+ result = yield request({
+ path: result["@odata.nextLink"]
+ });
+ files = files.concat(result.value.map(i => i.name));
+ }
+
+ return files;
+ });
+ return _list.apply(this, arguments);
+ }
+
+ function get(_x3) {
+ return _get.apply(this, arguments);
+ }
+
+ function _get() {
+ _get = _asyncToGenerator(function* (file) {
+ return yield query({
+ path: ":/".concat(file, ":/content"),
+ format: "text"
+ });
+ });
+ return _get.apply(this, arguments);
+ }
+
+ function put(_x4, _x5) {
+ return _put.apply(this, arguments);
+ }
+
+ function _put() {
+ _put = _asyncToGenerator(function* (file, data) {
+ yield query({
+ method: "PUT",
+ path: ":/".concat(file, ":/content"),
+ headers: {
+ "Content-Type": "text/plain"
+ },
+ body: data
+ });
+ });
+ return _put.apply(this, arguments);
+ }
+
+ function post(_x6, _x7) {
+ return _post.apply(this, arguments);
+ }
+
+ function _post() {
+ _post = _asyncToGenerator(function* (file, data) {
+ try {
+ yield query({
+ method: "PUT",
+ path: ":/".concat(file, ":/content?@microsoft.graph.conflictBehavior=fail"),
+ headers: {
+ "Content-Type": "text/plain"
+ },
+ body: data
+ });
+ } catch (err) {
+ if (err.code === 409 && err.message.includes("nameAlreadyExists")) {
+ err.code = "EEXIST";
+ }
+
+ throw err;
+ }
+ });
+ return _post.apply(this, arguments);
+ }
+
+ function delete_(_x8) {
+ return _delete_.apply(this, arguments);
+ }
+
+ function _delete_() {
+ _delete_ = _asyncToGenerator(function* (file) {
+ try {
+ yield query({
+ method: "DELETE",
+ path: ":/".concat(file, ":")
+ });
+ } catch (err) {
+ if (err.code === 404) {
+ return;
+ }
+
+ throw err;
+ }
+ });
+ return _delete_.apply(this, arguments);
+ }
+ }
+
+ function createDrive$1({
+ getAccessToken,
+ fetch = (typeof self !== "undefined" ? self : global).fetch,
+ FormData = (typeof self !== "undefined" ? self : global).FormData,
+ Blob = (typeof self !== "undefined" ? self : global).Blob
+ }) {
+ const request = createRequest({
+ fetch,
+ getAccessToken
+ });
+ const fileMetaCache = new Map();
+ let lockRev;
+ return {
+ name: "google",
+ get,
+ put,
+ post,
+ delete: delete_,
+ list,
+ init,
+ acquireLock,
+ releaseLock,
+ fileMetaCache
+ };
+
+ function revDelete(_x, _x2) {
+ return _revDelete.apply(this, arguments);
+ }
+
+ function _revDelete() {
+ _revDelete = _asyncToGenerator(function* (fileId, revId) {
+ yield request({
+ method: "DELETE",
+ path: "https://www.googleapis.com/drive/v3/files/".concat(fileId, "/revisions/").concat(revId)
+ });
+ });
+ return _revDelete.apply(this, arguments);
+ }
+
+ function acquireLock(_x3) {
+ return _acquireLock.apply(this, arguments);
+ }
+
+ function _acquireLock() {
+ _acquireLock = _asyncToGenerator(function* (expire) {
+ const lock = fileMetaCache.get("lock.json");
+
+ const _yield$queryPatch = yield queryPatch(lock.id, JSON.stringify({
+ expire: Date.now() + expire * 60 * 1000
+ })),
+ headRevisionId = _yield$queryPatch.headRevisionId;
+
+ const result = yield request({
+ path: "https://www.googleapis.com/drive/v3/files/".concat(lock.id, "/revisions?fields=revisions(id)")
+ });
+
+ for (let i = 1; i < result.revisions.length; i++) {
+ const revId = result.revisions[i].id;
+
+ if (revId === headRevisionId) {
+ // success
+ lockRev = headRevisionId;
+ return;
+ }
+
+ const rev = JSON.parse(yield request({
+ path: "https://www.googleapis.com/drive/v3/files/".concat(lock.id, "/revisions/").concat(revId, "?alt=media")
+ }));
+
+ if (rev.expire > Date.now()) {
+ // failed, delete the lock
+ yield revDelete(lock.id, headRevisionId);
+ throw new LockError(rev.expire);
+ } // delete outdated lock
+
+
+ yield revDelete(lock.id, revId);
+ }
+
+ throw new Error("cannot find lock revision");
+ });
+ return _acquireLock.apply(this, arguments);
+ }
+
+ function releaseLock() {
+ return _releaseLock.apply(this, arguments);
+ }
+
+ function _releaseLock() {
+ _releaseLock = _asyncToGenerator(function* () {
+ const lock = fileMetaCache.get("lock.json");
+ yield revDelete(lock.id, lockRev);
+ lockRev = null;
+ });
+ return _releaseLock.apply(this, arguments);
+ }
+
+ function queryList(_x4, _x5) {
+ return _queryList.apply(this, arguments);
+ }
+
+ function _queryList() {
+ _queryList = _asyncToGenerator(function* (path, onPage) {
+ path = "https://www.googleapis.com/drive/v3/files?spaces=appDataFolder&fields=nextPageToken,files(id,name,headRevisionId)" + (path ? "&" + path : "");
+ let result = yield request({
+ path
+ });
+ onPage(result);
+
+ while (result.nextPageToken) {
+ result = yield request({
+ path: "".concat(path, "&pageToken=").concat(result.nextPageToken)
+ });
+ onPage(result);
+ }
+ });
+ return _queryList.apply(this, arguments);
+ }
+
+ function queryPatch(_x6, _x7) {
+ return _queryPatch.apply(this, arguments);
+ }
+
+ function _queryPatch() {
+ _queryPatch = _asyncToGenerator(function* (id, text) {
+ return yield request({
+ method: "PATCH",
+ path: "https://www.googleapis.com/upload/drive/v3/files/".concat(id, "?uploadType=media&fields=headRevisionId"),
+ headers: {
+ "Content-Type": "text/plain"
+ },
+ body: text
+ });
+ });
+ return _queryPatch.apply(this, arguments);
+ }
+
+ function updateMeta(_x8) {
+ return _updateMeta.apply(this, arguments);
+ }
+
+ function _updateMeta() {
+ _updateMeta = _asyncToGenerator(function* (query) {
+ if (query) {
+ query = "q=".concat(encodeURIComponent(query));
+ }
+
+ yield queryList(query, result => {
+ var _iterator = _createForOfIteratorHelper(result.files),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ const file = _step.value;
+ fileMetaCache.set(file.name, file);
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+ });
+ });
+ return _updateMeta.apply(this, arguments);
+ }
+
+ function init() {
+ return _init.apply(this, arguments);
+ }
+
+ function _init() {
+ _init = _asyncToGenerator(function* () {
+ yield updateMeta();
+
+ if (!fileMetaCache.has("lock.json")) {
+ yield post("lock.json", "{}");
+ }
+
+ if (!fileMetaCache.has("meta.json")) {
+ yield post("meta.json", "{}");
+ }
+ });
+ return _init.apply(this, arguments);
+ }
+
+ function list(_x9) {
+ return _list.apply(this, arguments);
+ }
+
+ function _list() {
+ _list = _asyncToGenerator(function* (file) {
+ // FIXME: this only works if file is a single dir
+ // FIXME: this only works if the list method is called right after init, use
+ // queryList instead?
+ return [...fileMetaCache.values()].filter(f => f.name.startsWith(file + "/")).map(f => f.name.split("/")[1]);
+ });
+ return _list.apply(this, arguments);
+ }
+
+ function get(_x10) {
+ return _get.apply(this, arguments);
+ }
+
+ function _get() {
+ _get = _asyncToGenerator(function* (file) {
+ let meta = fileMetaCache.get(file);
+
+ if (!meta) {
+ yield updateMeta("name = '".concat(file, "'"));
+ meta = fileMetaCache.get(file);
+
+ if (!meta) {
+ throw new RequestError("metaCache doesn't contain ".concat(file), null, "ENOENT");
+ }
+ }
+
+ try {
+ return yield request({
+ path: "https://www.googleapis.com/drive/v3/files/".concat(meta.id, "?alt=media")
+ });
+ } catch (err) {
+ if (err.code === 404) {
+ err.code = "ENOENT";
+ }
+
+ throw err;
+ }
+ });
+ return _get.apply(this, arguments);
+ }
+
+ function put(_x11, _x12) {
+ return _put.apply(this, arguments);
+ }
+
+ function _put() {
+ _put = _asyncToGenerator(function* (file, data) {
+ if (!fileMetaCache.has(file)) {
+ return yield post(file, data);
+ }
+
+ const meta = fileMetaCache.get(file);
+ const result = yield queryPatch(meta.id, data);
+ meta.headRevisionId = result.headRevisionId;
+ });
+ return _put.apply(this, arguments);
+ }
+
+ function post(_x13, _x14) {
+ return _post.apply(this, arguments);
+ }
+
+ function _post() {
+ _post = _asyncToGenerator(function* (file, data) {
+ const body = new FormData();
+ const meta = {
+ name: file,
+ parents: ["appDataFolder"]
+ };
+ body.append("metadata", new Blob([JSON.stringify(meta)], {
+ type: "application/json; charset=UTF-8"
+ }));
+ body.append("media", new Blob([data], {
+ type: "text/plain"
+ }));
+ const result = yield request({
+ method: "POST",
+ path: "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,headRevisionId",
+ body
+ });
+ fileMetaCache.set(result.name, result);
+ });
+ return _post.apply(this, arguments);
+ }
+
+ function delete_(_x15) {
+ return _delete_.apply(this, arguments);
+ }
+
+ function _delete_() {
+ _delete_ = _asyncToGenerator(function* (file) {
+ const meta = fileMetaCache.get(file);
+
+ if (!meta) {
+ return;
+ }
+
+ try {
+ yield request({
+ method: "DELETE",
+ path: "https://www.googleapis.com/drive/v3/files/".concat(meta.id)
+ });
+ } catch (err) {
+ if (err.code === 404) {
+ return;
+ }
+
+ throw err;
+ }
+ });
+ return _delete_.apply(this, arguments);
+ }
+ }
+
+ function dirname(path) {
+ const dir = path.replace(/[/\\][^/\\]+\/?$/, "");
+ if (dir === path) return ".";
+ return dir;
+ }
+
+ const _excluded = ["path"];
+
+ function arrayify(o) {
+ return Array.isArray(o) ? o : [o];
+ }
+
+ function xmlToJSON(node) {
+ // FIXME: xmldom doesn't support children
+ const children = Array.prototype.filter.call(node.childNodes, i => i.nodeType === 1);
+
+ if (!children.length) {
+ return node.textContent;
+ }
+
+ const o = {};
+
+ var _iterator = _createForOfIteratorHelper(children),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ const c = _step.value;
+ const cResult = xmlToJSON(c);
+
+ if (!o[c.localName]) {
+ o[c.localName] = cResult;
+ } else if (!Array.isArray(o[c.localName])) {
+ const list = [o[c.localName]];
+ list.push(cResult);
+ o[c.localName] = list;
+ } else {
+ o[c.localName].push(cResult);
+ }
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+
+ return o;
+ }
+
+ function createDrive({
+ username,
+ password,
+ url,
+ fetch = (typeof self !== "undefined" ? self : global).fetch,
+ DOMParser = (typeof self !== "undefined" ? self : global).DOMParser
+ }) {
+ if (!url.endsWith("/")) {
+ url += "/";
+ }
+ const request = createRequest({
+ fetch,
+ username,
+ password
+ });
+ return {
+ name: "webdav",
+ get,
+ put,
+ post,
+ delete: delete_,
+ list // acquireLock,
+ // releaseLock
+
+ };
+
+ function requestDAV(_x) {
+ return _requestDAV.apply(this, arguments);
+ }
+
+ function _requestDAV() {
+ _requestDAV = _asyncToGenerator(function* (_ref) {
+ let path = _ref.path,
+ args = _objectWithoutProperties(_ref, _excluded);
+
+ const text = yield request(_objectSpread2({
+ path: "".concat(url).concat(path)
+ }, args));
+ if (args.format || typeof text !== "string" || !text) return text;
+ const parser = new DOMParser();
+ const xml = parser.parseFromString(text, "application/xml");
+ const result = xmlToJSON(xml);
+
+ if (result.error) {
+ throw new Error("Failed requesting DAV at ".concat(url).concat(path, ": ").concat(JSON.stringify(result.error)));
+ }
+
+ if (result.multistatus) {
+ result.multistatus.response = arrayify(result.multistatus.response);
+
+ var _iterator2 = _createForOfIteratorHelper(result.multistatus.response),
+ _step2;
+
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ const r = _step2.value;
+
+ if (r.error) {
+ throw new Error("Failed requesting DAV at ".concat(url).concat(path, ": ").concat(r.href, " ").concat(r.error));
+ }
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+ }
+
+ return result;
+ });
+ return _requestDAV.apply(this, arguments);
+ }
+
+ function list(_x2) {
+ return _list.apply(this, arguments);
+ }
+
+ function _list() {
+ _list = _asyncToGenerator(function* (file) {
+ if (!file.endsWith("/")) {
+ file += "/";
+ }
+
+ const result = yield requestDAV({
+ method: "PROPFIND",
+ path: file,
+ contentType: "application/xml",
+ body: " \n \n \n ",
+ headers: {
+ "Depth": "1"
+ }
+ });
+ const files = [];
+
+ var _iterator3 = _createForOfIteratorHelper(arrayify(result.multistatus.response)),
+ _step3;
+
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ const entry = _step3.value;
+
+ if (arrayify(entry.propstat).some(s => s.prop.resourcetype && s.prop.resourcetype.collection !== undefined)) {
+ continue;
+ }
+
+ const base = "".concat(url).concat(file);
+ const absUrl = new URL(entry.href, base).href;
+ const name = absUrl.slice(base.length);
+ files.push(name);
+ }
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
+
+ return files;
+ });
+ return _list.apply(this, arguments);
+ }
+
+ function get(_x3) {
+ return _get.apply(this, arguments);
+ }
+
+ function _get() {
+ _get = _asyncToGenerator(function* (file) {
+ return yield requestDAV({
+ method: "GET",
+ path: file,
+ format: "text"
+ });
+ });
+ return _get.apply(this, arguments);
+ }
+
+ function put(_x4, _x5) {
+ return _put.apply(this, arguments);
+ }
+
+ function _put() {
+ _put = _asyncToGenerator(function* (file, data) {
+ return yield withDir(dirname(file), () => requestDAV({
+ method: "PUT",
+ path: file,
+ contentType: "application/octet-stream",
+ body: data
+ }));
+ });
+ return _put.apply(this, arguments);
+ }
+
+ function withDir(_x6, _x7) {
+ return _withDir.apply(this, arguments);
+ }
+
+ function _withDir() {
+ _withDir = _asyncToGenerator(function* (dir, cb) {
+ try {
+ return yield cb();
+ } catch (err) {
+ if (err.code !== 409 && err.code !== 404 || dir === ".") {
+ throw err;
+ }
+ }
+
+ yield withDir(dirname(dir), () => requestDAV({
+ method: "MKCOL",
+ path: dir
+ }));
+ return yield cb();
+ });
+ return _withDir.apply(this, arguments);
+ }
+
+ function post(_x8, _x9) {
+ return _post.apply(this, arguments);
+ }
+
+ function _post() {
+ _post = _asyncToGenerator(function* (file, data) {
+ try {
+ return yield withDir(dirname(file), () => requestDAV({
+ method: "PUT",
+ path: file,
+ body: data,
+ contentType: "octet-stream",
+ headers: {
+ // FIXME: seems webdav-server doesn't support etag, what about others?
+ "If-None-Match": "*"
+ }
+ }));
+ } catch (err) {
+ if (err.code === 412) {
+ err.code = "EEXIST";
+ }
+
+ throw err;
+ }
+ });
+ return _post.apply(this, arguments);
+ }
+
+ function delete_(_x10) {
+ return _delete_.apply(this, arguments);
+ } // async function acquireLock(mins) {
+ // const r = await requestDAV({
+ // method: "LOCK",
+ // path: "",
+ // body:
+ // `
+ //
+ //
+ //
+ // `,
+ // headers: {
+ // "Timeout": `Second-${mins * 60}`
+ // },
+ // raw: true
+ // });
+ // lockToken = r.headers.get("Lock-Token");
+ // }
+ // async function releaseLock() {
+ // await requestDAV({
+ // method: "UNLOCK",
+ // path: "",
+ // headers: {
+ // "Lock-Token": lockToken
+ // }
+ // });
+ // }
+
+
+ function _delete_() {
+ _delete_ = _asyncToGenerator(function* (file) {
+ // FIXME: support deleting collections?
+ // FIXME: handle errors?
+ try {
+ yield requestDAV({
+ method: "DELETE",
+ path: file
+ });
+ } catch (err) {
+ if (err.code === 404) return;
+ throw err;
+ }
+ });
+ return _delete_.apply(this, arguments);
+ }
+ }
+
+ var index = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ fsDrive: empty,
+ github: createDrive$4,
+ dropbox: createDrive$3,
+ onedrive: createDrive$2,
+ google: createDrive$1,
+ webdav: createDrive
+ });
+
+ exports.dbToCloud = dbToCloud;
+ exports.drive = index;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+ return exports;
+
+}({}));
diff --git a/vendor/db-to-cloud/db-to-cloud.min.js b/vendor/db-to-cloud/db-to-cloud.min.js
deleted file mode 100644
index a0d4226d..00000000
--- a/vendor/db-to-cloud/db-to-cloud.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var dbToCloud=function(t){"use strict";function e(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function n(t){for(var n=1;n=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}function a(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null==n)return;var o,r,i=[],c=!0,a=!1;try{for(n=n.call(t);!(c=(o=n.next()).done)&&(i.push(o.value),!e||i.length!==e);c=!0);}catch(t){a=!0,r=t}finally{try{c||null==n.return||n.return()}finally{if(a)throw r}}return i}(t,e)||s(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,c=!0,a=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return c=t.done,t},e:function(t){a=!0,i=t},f:function(){try{c||null==n.return||n.return()}finally{if(a)throw i}}}}function p({maxActiveReader:t=1/0}={}){let e,n,o=0;const r={read:t=>i(t,!1),write:t=>i(t,!0),length:0};return r;function i(t,o){const i=function({fn:t,block:e=!1,prev:n,next:o,q:r=c(),q2:i=(t.length?c():null)}){return{fn:t,block:e,prev:n,next:o,q:r,q2:i}}({fn:t,block:o});return n?(n.next=i,i.prev=n,n=i,e||(e=n)):e=n=i,r.length++,a(),i.q.promise}function c(){const t={};return t.promise=new Promise(((e,n)=>{t.resolve=e,t.reject=n})),t}function a(){const i=e;if(!i||i.block&&i.prev||i.prev&&i.prev.block||o>=t)return;let c;i.block||o++,e=i.next;try{c=i.fn(i.q2&&i.q2.resolve)}catch(t){return i.q.reject(t),void s()}if(i.q2&&i.q2.promise.then(l),c&&c.then){const t=c.then(i.q.resolve,i.q.reject);i.q2||t.then(s)}else if(i.q.resolve(c),!i.q2)return void s();function s(){l()}function l(t){i.prev&&(i.prev.next=i.next),i.next&&(i.next.prev=i.prev),n===i&&(n=i.prev),i.block||o--,r.length--,t&&t(),a()}a()}}class f extends Error{constructor(t){super("The database is locked. Will expire at ".concat(new Date(t).toLocaleString())),this.expire=t,this.name="LockError",Error.captureStackTrace&&Error.captureStackTrace(this,f)}}function h(t){let e,n=0;return()=>(n&&clearTimeout(n),n=setTimeout(o),e||(e=function(){const t={};return t.promise=new Promise(((e,n)=>{t.resolve=e,t.reject=n})),t}()),e.promise);function o(){Promise.resolve(t()).then(e.resolve,e.reject),n=0,e=null}}function d(t){return new Promise((e=>setTimeout(e,t)))}function y(t){return String.fromCharCode(parseInt(t.slice(1),16))}function g(t){return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g,y))}function m(t){return"%".concat("00".concat(t.charCodeAt(0).toString(16)).slice(-2))}function v(t){return decodeURIComponent(Array.from(atob(t),m).join(""))}const w=["path","contentType","headers","format","raw"];class b extends Error{constructor(t,e,n=e&&e.status){super(t),this.code=n,this.origin=e,Error.captureStackTrace&&Error.captureStackTrace(this,b)}}function T({fetch:t,cooldown:e=0,getAccessToken:o,username:i,password:a}){const s=p(),l=i||a?"Basic ".concat(g("".concat(i,":").concat(a))):null;return t=>s.write(function(){var n=r((function*(n){try{return yield function(t){return u.apply(this,arguments)}(t)}finally{e&&t.method&&"GET"!==t.method?setTimeout(n,e):n()}}));return function(t){return n.apply(this,arguments)}}());function u(){return(u=r((function*(e){let r=e.path,i=e.contentType,a=e.headers,s=e.format,u=e.raw,p=void 0!==u&&u,f=c(e,w);const h={};for(o&&(h.Authorization="Bearer ".concat(yield o())),l&&(h.Authorization=l),i&&(h["Content-Type"]=i),Object.assign(h,a);;){const e=yield t(r,n({headers:h},f));if(!e.ok){const t=e.headers.get("Retry-After");if(t){const e=Number(t);if(e){yield d(1e3*e);continue}}const n=yield e.text();throw new b("failed to fetch [".concat(e.status,"]: ").concat(n),e)}if(p)return e;if(s)return yield e[s]();const o=e.headers.get("Content-Type");return/application\/json/.test(o)?yield e.json():yield e.text()}}))).apply(this,arguments)}}const E=["path","body"];function O(t){const e=t.replace(/[/\\][^/\\]+\/?$/,"");return e===t?".":e}const j=["path"];function k(t){return Array.isArray(t)?t:[t]}function x(t){const e=Array.prototype.filter.call(t.childNodes,(t=>1===t.nodeType));if(!e.length)return t.textContent;const n={};var o,r=u(e);try{for(r.s();!(o=r.n()).done;){const t=o.value,e=x(t);if(n[t.localName])if(Array.isArray(n[t.localName]))n[t.localName].push(e);else{const o=[n[t.localName]];o.push(e),n[t.localName]=o}else n[t.localName]=e}}catch(t){r.e(t)}finally{r.f()}return n}var C=Object.freeze({__proto__:null,fsDrive:()=>{},github:function({userAgent:t="db-to-cloud",owner:e,repo:n,getAccessToken:o,fetch:i=("undefined"!=typeof self?self:global).fetch}){const c=T({fetch:i,getAccessToken:o,cooldown:1e3}),a=new Map;return{name:"github",get:p,put:h,post:function(t,e){return h(t,e,!1)},delete:function(t){return y.apply(this,arguments)},list:function(t){return l.apply(this,arguments)},shaCache:a};function s(e){return e.headers||(e.headers={}),e.headers["User-Agent"]||(e.headers["User-Agent"]=t),e.headers.Accept||(e.headers.Accept="application/vnd.github.v3+json"),e.path="https://api.github.com".concat(e.path),c(e)}function l(){return(l=r((function*(t){const o=[];var r,i=u(yield s({path:"/repos/".concat(e,"/").concat(n,"/contents/").concat(t)}));try{for(i.s();!(r=i.n()).done;){const t=r.value;o.push(t.name),a.set(t.path,t.sha)}}catch(t){i.e(t)}finally{i.f()}return o}))).apply(this,arguments)}function p(t){return f.apply(this,arguments)}function f(){return(f=r((function*(t){const o=yield s({path:"/repos/".concat(e,"/").concat(n,"/contents/").concat(t)});return a.set(o.path,o.sha),v(o.content)}))).apply(this,arguments)}function h(t,e){return d.apply(this,arguments)}function d(){return(d=r((function*(t,o,r=!0){const i={message:"",content:g(o)};r&&a.has(t)&&(i.sha=a.get(t));const c={method:"PUT",path:"/repos/".concat(e,"/").concat(n,"/contents/").concat(t),contentType:"application/json",body:JSON.stringify(i)};let l,u=!1;for(;!l;){try{l=yield s(c)}catch(e){if(422!==e.code||!e.message.includes('\\"sha\\" wasn\'t supplied'))throw e;if(!r||u)throw e.code="EEXIST",e;yield p(t)}u=!0}a.set(t,l.content.sha)}))).apply(this,arguments)}function y(){return(y=r((function*(t){try{let o=a.get(t);o||(yield p(t),o=a.get(t)),yield s({method:"DELETE",path:"/repos/".concat(e,"/").concat(n,"/contents/").concat(t),body:JSON.stringify({message:"",sha:o})})}catch(t){if(404===t.code)return;throw t}}))).apply(this,arguments)}},dropbox:function({getAccessToken:t,fetch:e=("undefined"!=typeof self?self:global).fetch}){const o=T({fetch:e,getAccessToken:t});return{name:"dropbox",get:function(t){return l.apply(this,arguments)},put:p,post:function(t,e){return h.apply(this,arguments)},delete:function(t){return d.apply(this,arguments)},list:function(t){return a.apply(this,arguments)}};function i(t){let e=t.path,r=t.body,i=c(t,E);return o(n({method:"POST",path:"https://api.dropboxapi.com/2/".concat(e),contentType:"application/json",body:JSON.stringify(r)},i))}function a(){return(a=r((function*(t){const e=[];let n=yield i({path:"files/list_folder",body:{path:"/".concat(t)}});var o,r=u(n.entries);try{for(r.s();!(o=r.n()).done;){const t=o.value;e.push(t.name)}}catch(t){r.e(t)}finally{r.f()}if(!n.has_more)return e;for(;n.has_more;){n=yield i({path:"files/list_folder/continue",body:{cursor:n.cursor}});var c,a=u(n.entries);try{for(a.s();!(c=a.n()).done;){const t=c.value;e.push(t.name)}}catch(t){a.e(t)}finally{a.f()}}return e}))).apply(this,arguments)}function s(t){const e=new URLSearchParams;return e.set("arg",JSON.stringify(t)),e.toString()}function l(){return(l=r((function*(t){const e={path:"/".concat(t)};try{return yield o({path:"https://content.dropboxapi.com/2/files/download?".concat(s(e)),format:"text"})}catch(t){throw 409===t.code&&t.message.includes("not_found")&&(t.code="ENOENT"),t}}))).apply(this,arguments)}function p(t,e){return f.apply(this,arguments)}function f(){return(f=r((function*(t,e,n="overwrite"){const r={path:"/".concat(t),mode:n,autorename:!1,mute:!0};yield o({path:"https://content.dropboxapi.com/2/files/upload?".concat(s(r)),method:"POST",contentType:"application/octet-stream",body:e})}))).apply(this,arguments)}function h(){return(h=r((function*(t,e){try{return yield p(t,e,"add")}catch(t){throw 409===t.code&&t.message.includes("conflict")&&(t.code="EEXIST"),t}}))).apply(this,arguments)}function d(){return(d=r((function*(t){try{yield i({path:"files/delete_v2",body:{path:"/".concat(t)}})}catch(t){if(409===t.code&&t.message.includes("not_found"))return;throw t}}))).apply(this,arguments)}},onedrive:function({getAccessToken:t,fetch:e=("undefined"!=typeof self?self:global).fetch}){const n=T({fetch:e,getAccessToken:t});return{name:"onedrive",get:function(t){return a.apply(this,arguments)},put:function(t,e){return s.apply(this,arguments)},post:function(t,e){return l.apply(this,arguments)},delete:function(t){return u.apply(this,arguments)},list:function(t){return c.apply(this,arguments)}};function o(t){return i.apply(this,arguments)}function i(){return(i=r((function*(t){return t.path="https://graph.microsoft.com/v1.0/me/drive/special/approot".concat(t.path),yield n(t)}))).apply(this,arguments)}function c(){return(c=r((function*(t){t&&(t=":/".concat(t,":"));let e=yield o({path:"".concat(t,"/children?select=name")}),r=e.value.map((t=>t.name));for(;e["@odata.nextLink"];)e=yield n({path:e["@odata.nextLink"]}),r=r.concat(e.value.map((t=>t.name)));return r}))).apply(this,arguments)}function a(){return(a=r((function*(t){return yield o({path:":/".concat(t,":/content"),format:"text"})}))).apply(this,arguments)}function s(){return(s=r((function*(t,e){yield o({method:"PUT",path:":/".concat(t,":/content"),headers:{"Content-Type":"text/plain"},body:e})}))).apply(this,arguments)}function l(){return(l=r((function*(t,e){try{yield o({method:"PUT",path:":/".concat(t,":/content?@microsoft.graph.conflictBehavior=fail"),headers:{"Content-Type":"text/plain"},body:e})}catch(t){throw 409===t.code&&t.message.includes("nameAlreadyExists")&&(t.code="EEXIST"),t}}))).apply(this,arguments)}function u(){return(u=r((function*(t){try{yield o({method:"DELETE",path:":/".concat(t,":")})}catch(t){if(404===t.code)return;throw t}}))).apply(this,arguments)}},google:function({getAccessToken:t,fetch:e=("undefined"!=typeof self?self:global).fetch,FormData:n=("undefined"!=typeof self?self:global).FormData,Blob:o=("undefined"!=typeof self?self:global).Blob}){const i=T({fetch:e,getAccessToken:t}),c=new Map;let a;return{name:"google",get:function(t){return j.apply(this,arguments)},put:function(t,e){return k.apply(this,arguments)},post:x,delete:function(t){return S.apply(this,arguments)},list:function(t){return O.apply(this,arguments)},init:function(){return E.apply(this,arguments)},acquireLock:function(t){return p.apply(this,arguments)},releaseLock:function(){return h.apply(this,arguments)},fileMetaCache:c};function s(t,e){return l.apply(this,arguments)}function l(){return(l=r((function*(t,e){yield i({method:"DELETE",path:"https://www.googleapis.com/drive/v3/files/".concat(t,"/revisions/").concat(e)})}))).apply(this,arguments)}function p(){return(p=r((function*(t){const e=c.get("lock.json"),n=(yield g(e.id,JSON.stringify({expire:Date.now()+60*t*1e3}))).headRevisionId,o=yield i({path:"https://www.googleapis.com/drive/v3/files/".concat(e.id,"/revisions?fields=revisions(id)")});for(let t=1;tDate.now())throw yield s(e.id,n),new f(c.expire);yield s(e.id,r)}throw new Error("cannot find lock revision")}))).apply(this,arguments)}function h(){return(h=r((function*(){const t=c.get("lock.json");yield s(t.id,a),a=null}))).apply(this,arguments)}function d(t,e){return y.apply(this,arguments)}function y(){return(y=r((function*(t,e){t="https://www.googleapis.com/drive/v3/files?spaces=appDataFolder&fields=nextPageToken,files(id,name,headRevisionId)"+(t?"&"+t:"");let n=yield i({path:t});for(e(n);n.nextPageToken;)n=yield i({path:"".concat(t,"&pageToken=").concat(n.nextPageToken)}),e(n)}))).apply(this,arguments)}function g(t,e){return m.apply(this,arguments)}function m(){return(m=r((function*(t,e){return yield i({method:"PATCH",path:"https://www.googleapis.com/upload/drive/v3/files/".concat(t,"?uploadType=media&fields=headRevisionId"),headers:{"Content-Type":"text/plain"},body:e})}))).apply(this,arguments)}function v(t){return w.apply(this,arguments)}function w(){return(w=r((function*(t){t&&(t="q=".concat(encodeURIComponent(t))),yield d(t,(t=>{var e,n=u(t.files);try{for(n.s();!(e=n.n()).done;){const t=e.value;c.set(t.name,t)}}catch(t){n.e(t)}finally{n.f()}}))}))).apply(this,arguments)}function E(){return(E=r((function*(){yield v(),c.has("lock.json")||(yield x("lock.json","{}")),c.has("meta.json")||(yield x("meta.json","{}"))}))).apply(this,arguments)}function O(){return(O=r((function*(t){return[...c.values()].filter((e=>e.name.startsWith(t+"/"))).map((t=>t.name.split("/")[1]))}))).apply(this,arguments)}function j(){return(j=r((function*(t){let e=c.get(t);if(!e&&(yield v("name = '".concat(t,"'")),e=c.get(t),!e))throw new b("metaCache doesn't contain ".concat(t),null,"ENOENT");try{return yield i({path:"https://www.googleapis.com/drive/v3/files/".concat(e.id,"?alt=media")})}catch(t){throw 404===t.code&&(t.code="ENOENT"),t}}))).apply(this,arguments)}function k(){return(k=r((function*(t,e){if(!c.has(t))return yield x(t,e);const n=c.get(t),o=yield g(n.id,e);n.headRevisionId=o.headRevisionId}))).apply(this,arguments)}function x(t,e){return C.apply(this,arguments)}function C(){return(C=r((function*(t,e){const r=new n,a={name:t,parents:["appDataFolder"]};r.append("metadata",new o([JSON.stringify(a)],{type:"application/json; charset=UTF-8"})),r.append("media",new o([e],{type:"text/plain"}));const s=yield i({method:"POST",path:"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,headRevisionId",body:r});c.set(s.name,s)}))).apply(this,arguments)}function S(){return(S=r((function*(t){const e=c.get(t);if(e)try{yield i({method:"DELETE",path:"https://www.googleapis.com/drive/v3/files/".concat(e.id)})}catch(t){if(404===t.code)return;throw t}}))).apply(this,arguments)}},webdav:function({username:t,password:e,url:o,fetch:i=("undefined"!=typeof self?self:global).fetch,DOMParser:a=("undefined"!=typeof self?self:global).DOMParser}){o.endsWith("/")||(o+="/");const s=T({fetch:i,username:t,password:e});return{name:"webdav",get:function(t){return h.apply(this,arguments)},put:function(t,e){return d.apply(this,arguments)},post:function(t,e){return m.apply(this,arguments)},delete:function(t){return v.apply(this,arguments)},list:function(t){return f.apply(this,arguments)}};function l(t){return p.apply(this,arguments)}function p(){return(p=r((function*(t){let e=t.path,r=c(t,j);const i=yield s(n({path:"".concat(o).concat(e)},r));if(r.format||"string"!=typeof i||!i)return i;const l=x((new a).parseFromString(i,"application/xml"));if(l.error)throw new Error("Failed requesting DAV at ".concat(o).concat(e,": ").concat(JSON.stringify(l.error)));if(l.multistatus){l.multistatus.response=k(l.multistatus.response);var p,f=u(l.multistatus.response);try{for(f.s();!(p=f.n()).done;){const t=p.value;if(t.error)throw new Error("Failed requesting DAV at ".concat(o).concat(e,": ").concat(t.href," ").concat(t.error))}}catch(t){f.e(t)}finally{f.f()}}return l}))).apply(this,arguments)}function f(){return(f=r((function*(t){t.endsWith("/")||(t+="/");const e=[];var n,r=u(k((yield l({method:"PROPFIND",path:t,contentType:"application/xml",body:' \n \n \n ',headers:{Depth:"1"}})).multistatus.response));try{for(r.s();!(n=r.n()).done;){const r=n.value;if(k(r.propstat).some((t=>t.prop.resourcetype&&void 0!==t.prop.resourcetype.collection)))continue;const i="".concat(o).concat(t),c=new URL(r.href,i).href.slice(i.length);e.push(c)}}catch(t){r.e(t)}finally{r.f()}return e}))).apply(this,arguments)}function h(){return(h=r((function*(t){return yield l({method:"GET",path:t,format:"text"})}))).apply(this,arguments)}function d(){return(d=r((function*(t,e){return yield y(O(t),(()=>l({method:"PUT",path:t,contentType:"application/octet-stream",body:e})))}))).apply(this,arguments)}function y(t,e){return g.apply(this,arguments)}function g(){return(g=r((function*(t,e){try{return yield e()}catch(e){if(409!==e.code&&404!==e.code||"."===t)throw e}return yield y(O(t),(()=>l({method:"MKCOL",path:t}))),yield e()}))).apply(this,arguments)}function m(){return(m=r((function*(t,e){try{return yield y(O(t),(()=>l({method:"PUT",path:t,body:e,contentType:"octet-stream",headers:{"If-None-Match":"*"}})))}catch(t){throw 412===t.code&&(t.code="EEXIST"),t}}))).apply(this,arguments)}function v(){return(v=r((function*(t){try{yield l({method:"DELETE",path:t})}catch(t){if(404===t.code)return;throw t}}))).apply(this,arguments)}}});return t.dbToCloud=function({onGet:t,onPut:e,onDelete:n,onFirstSync:o,onWarn:i=console.error,onProgress:c,compareRevision:s,getState:l,setState:y,lockExpire:g=60,retryMaxAttempts:m=5,retryExp:v=1.5,retryDelay:w=10}){let b,T,E;const O=new Map,j=h((()=>y(b,T))),k=new Map,x=p();return{use:function(t){b=function(t){const e=Object.create(t);return e.get=function(){var e=r((function*(e){return JSON.parse(yield t.get(e))}));return function(t){return e.apply(this,arguments)}}(),e.put=function(){var e=r((function*(e,n){return yield t.put(e,JSON.stringify(n))}));return function(t,n){return e.apply(this,arguments)}}(),e.post=function(){var e=r((function*(e,n){return yield t.post(e,JSON.stringify(n))}));return function(t,n){return e.apply(this,arguments)}}(),e.isInit=!1,e.acquireLock||(e.acquireLock=function(t){return n.apply(this,arguments)},e.releaseLock=function(){return o.apply(this,arguments)}),e.getMeta||(e.getMeta=function(){return i.apply(this,arguments)},e.putMeta=function(t){return c.apply(this,arguments)}),e.peekChanges||(e.peekChanges=function(t){return a.apply(this,arguments)}),e;function n(){return(n=r((function*(t){try{yield this.post("lock.json",{expire:Date.now()+60*t*1e3})}catch(t){if("EEXIST"!==t.code)throw t;const e=yield this.get("lock.json");if(Date.now()>e.expire)throw yield this.delete("lock.json"),new Error("Found expired lock, please try again");throw new f(e.expire)}}))).apply(this,arguments)}function o(){return(o=r((function*(){yield this.delete("lock.json")}))).apply(this,arguments)}function i(){return(i=r((function*(){try{return yield this.get("meta.json")}catch(t){if("ENOENT"===t.code||404===t.code)return{};throw t}}))).apply(this,arguments)}function c(){return(c=r((function*(t){yield this.put("meta.json",t)}))).apply(this,arguments)}function a(){return(a=r((function*(t){return(yield this.getMeta()).lastChange!==t.lastChange}))).apply(this,arguments)}}(t)},init:function(){return x.write(r((function*(){if(!T||!T.enabled){if(!b)throw new Error("cloud drive is undefined");T=(yield l(b))||{},T.enabled=!0,T.queue||(T.queue=[])}})))},uninit:function(){return x.write(r((function*(){T&&T.enabled&&(T=E=null,O.clear(),k.clear(),b.uninit&&b.isInit&&(yield b.uninit(),b.isInit=!1),yield j())})))},put:function(t,e){if(!T||!T.enabled)return;T.queue.push({_id:t,_rev:e,action:"put"}),j()},delete:function(t,e){if(!T||!T.enabled)return;T.queue.push({_id:t,_rev:e,action:"delete"}),j()},syncNow:function(t){return x.write(r((function*(){if(!T||!T.enabled)throw new Error("Cannot sync now, the sync is not enabled");b.init&&!b.isInit&&(yield b.init(),b.isInit=!0),null==T.lastChange&&(yield o()),yield function(){return q.apply(this,arguments)}(t)})))},drive:()=>b,isInit:()=>Boolean(T&&T.enabled)};function C(){return S.apply(this,arguments)}function S(){return(S=r((function*(){if(E=yield b.getMeta(),!E.lastChange||E.lastChange===T.lastChange)return;let t=[];if(T.lastChange){const e=Math.floor((E.lastChange-1)/100);let n=Math.floor(T.lastChange/100);for(;n<=e;){const e=yield b.get("changes/".concat(n,".json"));O.set(n,e),t=t.concat(e),n++}t=t.slice(T.lastChange%100)}else t=(yield b.list("docs")).map((t=>({action:"put",_id:t.slice(0,-5)})));const o=new Map;var r,s=u(t);try{for(s.s();!(r=s.n()).done;){const t=r.value;o.set(t._id,t)}}catch(t){s.e(t)}finally{s.f()}let l=0;var p,f=u(o);try{for(f.s();!(p=f.n()).done;){const t=a(p.value,2),r=t[0],s=t[1];let u,f;if(c&&c({phase:"pull",total:o.size,loaded:l,change:s}),"delete"===s.action)yield n(r,s._rev);else if("put"===s.action){try{var h=yield b.get("docs/".concat(r,".json"));u=h.doc,f=h._rev}catch(t){if("ENOENT"===t.code||404===t.code){i("Cannot find ".concat(r,". Is it deleted without updating the history?")),l++;continue}throw t}yield e(u)}const d=s._rev||f;d&&k.set(r,d),l++}}catch(t){f.e(t)}finally{f.f()}T.lastChange=E.lastChange,yield j()}))).apply(this,arguments)}function A(){return P.apply(this,arguments)}function P(){return(P=r((function*(){if(!T.queue.length)return;const e=T.queue.slice(),n=new Map;var o,r=u(e);try{for(r.s();!(o=r.n()).done;){const t=o.value;n.set(t._id,t)}}catch(t){r.e(t)}finally{r.f()}const i=[];var a,l=u(n.values());try{for(l.s();!(a=l.n()).done;){const t=a.value,e=k.get(t._id);void 0!==e&&s(t._rev,e)<=0||i.push(t)}}catch(t){l.e(t)}finally{l.f()}let p,f,h=0;for(var d=0,y=i;d=m)throw t;yield d(1e3*n),n*=v}try{yield C(),yield A()}finally{yield b.releaseLock()}}))).apply(this,arguments)}function q(){return(q=r((function*(t=!0){c&&c({phase:"start"});try{if(!T.queue.length&&t&&E){if(!(yield b.peekChanges(E)))return}yield _()}finally{c&&c({phase:"end"})}}))).apply(this,arguments)}},t.drive=C,Object.defineProperty(t,"__esModule",{value:!0}),t}({});
-//# sourceMappingURL=db-to-cloud.min.js.map
diff --git a/vendor/draggable-list/README.md b/vendor/draggable-list/README.md
index 95ece691..3f02a6ff 100644
--- a/vendor/draggable-list/README.md
+++ b/vendor/draggable-list/README.md
@@ -1,4 +1,4 @@
## @eight04/draggable-list v0.3.0
Files copied from NPM (node_modules):
-* draggable-list.iife.min.js: dist/*
+* draggable-list.iife.js: dist/*
diff --git a/vendor/draggable-list/draggable-list.iife.js b/vendor/draggable-list/draggable-list.iife.js
new file mode 100644
index 00000000..85e9d274
--- /dev/null
+++ b/vendor/draggable-list/draggable-list.iife.js
@@ -0,0 +1,166 @@
+var DraggableList = (function () {
+ 'use strict';
+
+ /* eslint-env browser */
+ const CLS_TRANSFORMED = 'draggable-list-transformed';
+ function posToIndex(rects, startIndex, y, bound) {
+ if (y < rects[0].top && bound) return startIndex;
+
+ for (let i = 0; i < startIndex; i++) {
+ if (rects[i].bottom < y) continue;
+ return i;
+ }
+
+ if (y > rects[rects.length - 1].bottom && bound) return startIndex;
+
+ for (let i = rects.length - 1; i > startIndex; i--) {
+ if (rects[i].top > y) continue;
+ return i;
+ }
+
+ return startIndex;
+ }
+ function applyTransform(list, startIndex, oldIndex, newIndex, len) {
+ if (newIndex > oldIndex) {
+ transform(false, oldIndex, Math.min(startIndex - 1, newIndex - 1));
+
+ if (startIndex < list.length - 1) {
+ transform(true, Math.max(oldIndex + 1, startIndex + 1), newIndex, "translateY(".concat(-len, "px)"));
+ }
+ } else {
+ transform(false, Math.max(startIndex + 1, newIndex + 1), oldIndex);
+
+ if (startIndex > 0) {
+ transform(true, newIndex, Math.min(oldIndex - 1, startIndex - 1), "translateY(".concat(len, "px)"));
+ }
+ }
+
+ function transform(state, p, q, style) {
+ for (let i = p; i <= q; i++) {
+ if (state && !list[i].classList.contains(CLS_TRANSFORMED)) {
+ list[i].classList.add(CLS_TRANSFORMED);
+ list[i].style.transform = style;
+ } else if (!state && list[i].classList.contains(CLS_TRANSFORMED)) {
+ list[i].classList.remove(CLS_TRANSFORMED);
+ list[i].style = '';
+ }
+ }
+ }
+ }
+ function DraggableList(el, {
+ bound,
+ scrollContainer
+ } = {}) {
+ for (const c of el.children) {
+ c.draggable = true;
+ }
+
+ new MutationObserver(records => {
+ for (const r of records) {
+ for (const n of r.addedNodes) {
+ n.draggable = true;
+ }
+ }
+ }).observe(el, {
+ childList: true
+ });
+ let startPos = null;
+ let startIndex = 0;
+ let dragOverIndex = 0;
+ let dragOverPos = null;
+ let rects = [];
+ let dragTarget = null;
+ let dropped = false;
+ let itemSize = 0;
+ el.addEventListener('dragstart', e => {
+ if (e.target.parentNode !== el) return;
+ dragTarget = e.target;
+ dropped = false;
+ const scrollLeft = scrollContainer ? scrollContainer.scrollLeft : 0;
+ const scrollTop = scrollContainer ? scrollContainer.scrollTop : 0;
+ startPos = {
+ x: e.pageX + scrollLeft,
+ y: e.pageY + scrollTop
+ };
+ startIndex = [...el.children].indexOf(e.target);
+ dragOverIndex = startIndex;
+ dragOverPos = startPos;
+ rects = [...el.children].map(el => {
+ const r = el.getBoundingClientRect();
+ return {
+ top: r.top + window.scrollY + scrollTop,
+ bottom: r.bottom + window.scrollY + scrollTop
+ };
+ });
+ itemSize = startIndex + 1 < rects.length ? rects[startIndex + 1].top - rects[startIndex].top : startIndex > 0 ? rects[startIndex].bottom - rects[startIndex - 1].bottom : 0;
+ dragTarget.classList.add('draggable-list-target');
+ el.classList.add('draggable-list-dragging');
+ dispatch(e, 'd:dragstart');
+ });
+ el.addEventListener('dragenter', e => {
+ if (dragTarget) {
+ e.preventDefault();
+ dispatch(e, 'd:dragmove');
+ }
+ });
+ el.addEventListener('dragover', e => {
+ if (!dragTarget) return;
+ e.preventDefault();
+ const scrollLeft = scrollContainer ? scrollContainer.scrollLeft : 0;
+ const scrollTop = scrollContainer ? scrollContainer.scrollTop : 0;
+ const newPos = {
+ x: e.pageX + scrollLeft,
+ y: e.pageY + scrollTop
+ };
+ const newIndex = posToIndex(rects, startIndex, newPos.y, bound);
+ applyTransform(el.children, startIndex, dragOverIndex, newIndex, itemSize);
+ dragOverIndex = newIndex;
+ dragOverPos = newPos;
+ dispatch(e, 'd:dragmove');
+ });
+ document.addEventListener('dragend', e => {
+ if (!dragTarget) return;
+
+ for (const c of el.children) {
+ c.classList.remove(CLS_TRANSFORMED);
+ c.style = '';
+ }
+
+ dragTarget.classList.remove('draggable-list-target');
+ el.classList.remove('draggable-list-dragging');
+ dispatch(e, 'd:dragend', {
+ originalIndex: startIndex,
+ spliceIndex: dragOverIndex,
+ insertBefore: dragOverIndex < startIndex ? el.children[dragOverIndex] : el.children[dragOverIndex + 1],
+ dropped
+ });
+ dragTarget = null;
+ });
+ el.addEventListener('drop', e => {
+ if (dragTarget) {
+ dropped = true;
+ e.preventDefault();
+ }
+ });
+
+ function dispatch(e, name, props) {
+ const detail = {
+ origin: e,
+ startPos,
+ currentPos: dragOverPos,
+ dragTarget
+ };
+
+ if (props) {
+ Object.assign(detail, props);
+ }
+
+ el.dispatchEvent(new CustomEvent(name, {
+ detail
+ }));
+ }
+ }
+
+ return DraggableList;
+
+})();
diff --git a/vendor/draggable-list/draggable-list.iife.min.js b/vendor/draggable-list/draggable-list.iife.min.js
deleted file mode 100644
index 3e49567b..00000000
--- a/vendor/draggable-list/draggable-list.iife.min.js
+++ /dev/null
@@ -1 +0,0 @@
-var DraggableList=function(){"use strict";const t="draggable-list-transformed";return function(e,{bound:r,scrollContainer:n}={}){for(const t of e.children)t.draggable=!0;new MutationObserver((t=>{for(const e of t)for(const t of e.addedNodes)t.draggable=!0})).observe(e,{childList:!0});let a=null,o=0,s=0,l=null,d=[],i=null,c=!1,g=0;function f(t,r,n){const o={origin:t,startPos:a,currentPos:l,dragTarget:i};n&&Object.assign(o,n),e.dispatchEvent(new CustomEvent(r,{detail:o}))}e.addEventListener("dragstart",(t=>{if(t.target.parentNode!==e)return;i=t.target,c=!1;const r=n?n.scrollLeft:0,u=n?n.scrollTop:0;a={x:t.pageX+r,y:t.pageY+u},o=[...e.children].indexOf(t.target),s=o,l=a,d=[...e.children].map((t=>{const e=t.getBoundingClientRect();return{top:e.top+window.scrollY+u,bottom:e.bottom+window.scrollY+u}})),g=o+10?d[o].bottom-d[o-1].bottom:0,i.classList.add("draggable-list-target"),e.classList.add("draggable-list-dragging"),f(t,"d:dragstart")})),e.addEventListener("dragenter",(t=>{i&&(t.preventDefault(),f(t,"d:dragmove"))})),e.addEventListener("dragover",(a=>{if(!i)return;a.preventDefault();const c=n?n.scrollLeft:0,u=n?n.scrollTop:0,p={x:a.pageX+c,y:a.pageY+u},m=function(t,e,r,n){if(rt[t.length-1].bottom&&n)return e;for(let n=t.length-1;n>e;n--)if(!(t[n].top>r))return n;return e}(d,o,p.y,r);!function(e,r,n,a,o){function s(r,n,a,o){for(let s=n;s<=a;s++)r&&!e[s].classList.contains(t)?(e[s].classList.add(t),e[s].style.transform=o):!r&&e[s].classList.contains(t)&&(e[s].classList.remove(t),e[s].style="")}a>n?(s(!1,n,Math.min(r-1,a-1)),r0&&s(!0,a,Math.min(n-1,r-1),"translateY(".concat(o,"px)")))}(e.children,o,s,m,g),s=m,l=p,f(a,"d:dragmove")})),document.addEventListener("dragend",(r=>{if(i){for(const r of e.children)r.classList.remove(t),r.style="";i.classList.remove("draggable-list-target"),e.classList.remove("draggable-list-dragging"),f(r,"d:dragend",{originalIndex:o,spliceIndex:s,insertBefore:s{i&&(c=!0,t.preventDefault())}))}}();
diff --git a/vendor/usercss-meta/README.md b/vendor/usercss-meta/README.md
index 3dbc3e59..7606315e 100644
--- a/vendor/usercss-meta/README.md
+++ b/vendor/usercss-meta/README.md
@@ -1,4 +1,4 @@
## usercss-meta v0.12.0
Files copied from NPM (node_modules):
-* usercss-meta.min.js: dist/*
+* usercss-meta.js: dist/* (removed sourceMappingURL)
diff --git a/vendor/usercss-meta/usercss-meta.js b/vendor/usercss-meta/usercss-meta.js
new file mode 100644
index 00000000..be586c57
--- /dev/null
+++ b/vendor/usercss-meta/usercss-meta.js
@@ -0,0 +1,1067 @@
+var usercssMeta = (function (exports) {
+ 'use strict';
+
+ class ParseError extends Error {
+ constructor(err) {
+ super(err.message);
+ delete err.message;
+ this.name = 'ParseError';
+ Object.assign(this, err);
+ }
+ }
+
+ class MissingCharError extends ParseError {
+ constructor(chars, index) {
+ super({
+ code: 'missingChar',
+ args: chars,
+ message: `Missing character: ${chars.map(c => `'${c}'`).join(', ')}`,
+ index
+ });
+ }
+ }
+
+ class EOFError extends ParseError {
+ constructor(index) {
+ super({
+ code: 'EOF',
+ message: 'Unexpected end of file',
+ index
+ });
+ }
+ }
+
+ const RX_EOT = /<< {
+ if (s[1] === q) {
+ return q;
+ }
+
+ return JSON.parse(`"${s}"`);
+ }
+ );
+ }
+
+ return unescapeComment(s);
+ }
+
+ function eatLine(state) {
+ RX_LINE.lastIndex = state.lastIndex;
+ RX_LINE.exec(state.text);
+ state.lastIndex = RX_LINE.lastIndex;
+ }
+
+ function eatWhitespace(state) {
+ RX_WHITESPACE.lastIndex = state.lastIndex;
+ state.lastIndex += RX_WHITESPACE.exec(state.text)[0].length;
+ }
+
+ function eatSameLineWhitespace(state) {
+ RX_WHITESPACE_SAMELINE.lastIndex = state.lastIndex;
+ state.lastIndex += RX_WHITESPACE_SAMELINE.exec(state.text)[0].length;
+ }
+
+ function parseChar(state) {
+ if (state.lastIndex >= state.text.length) {
+ throw new EOFError(state.lastIndex);
+ }
+
+ state.index = state.lastIndex;
+ state.value = state.text[state.lastIndex];
+ state.lastIndex++;
+ eatWhitespace(state);
+ }
+
+ function parseWord(state) {
+ const pos = state.lastIndex;
+ RX_WORD.lastIndex = pos;
+ const match = RX_WORD.exec(state.text);
+ if (!match) {
+ throw new ParseError({
+ code: 'invalidWord',
+ message: 'Invalid word',
+ index: pos
+ });
+ }
+
+ state.index = pos;
+ state.value = match[1];
+ state.lastIndex += match[0].length;
+ }
+
+ function parseJSON(state) {
+ const pos = state.lastIndex;
+ try {
+ parseJSONValue(state);
+ } catch (err) {
+ err.message = `Invalid JSON: ${err.message}`;
+ throw err;
+ }
+
+ state.index = pos;
+ }
+
+ function parseEOT(state) {
+ const pos = state.lastIndex;
+ RX_EOT.lastIndex = pos;
+ const match = RX_EOT.exec(state.text);
+ if (!match) {
+ throw new ParseError({
+ code: 'missingEOT',
+ message: 'Missing EOT',
+ index: pos
+ });
+ }
+
+ state.index = pos;
+ state.lastIndex += match[0].length;
+ state.value = unescapeComment(match[1].trim());
+ eatWhitespace(state);
+ }
+
+ function parseStringUnquoted(state) {
+ RX_STRING_UNQUOTED.lastIndex = state.lastIndex;
+ const match = RX_STRING_UNQUOTED.exec(state.text);
+ state.index = state.lastIndex;
+ state.lastIndex = RX_STRING_UNQUOTED.lastIndex;
+ state.value = match[0].trim().replace(/\s+/g, '-');
+ }
+
+ function parseString(state, sameLine = false) {
+ const pos = state.lastIndex;
+ const rx = state.text[pos] === '`' ? RX_STRING_BACKTICK : RX_STRING_QUOTED;
+ rx.lastIndex = pos;
+ const match = rx.exec(state.text);
+ if (!match) {
+ throw new ParseError({
+ code: 'invalidString',
+ message: 'Invalid string',
+ index: pos
+ });
+ }
+
+ state.index = pos;
+ state.lastIndex += match[0].length;
+ state.value = unquote(match[1]);
+ if (sameLine) {
+ eatSameLineWhitespace(state);
+ } else {
+ eatWhitespace(state);
+ }
+ }
+
+ function parseJSONValue(state) {
+ const {text} = state;
+ if (text[state.lastIndex] === '{') {
+ // object
+ const object = {};
+ state.lastIndex++;
+ eatWhitespace(state);
+ while (text[state.lastIndex] !== '}') {
+ parseString(state);
+ const key = state.value;
+ if (text[state.lastIndex] !== ':') {
+ throw new MissingCharError([':'], state.lastIndex);
+ }
+
+ state.lastIndex++;
+ eatWhitespace(state);
+ parseJSONValue(state);
+ object[key] = state.value;
+ if (text[state.lastIndex] === ',') {
+ state.lastIndex++;
+ eatWhitespace(state);
+ } else if (text[state.lastIndex] !== '}') {
+ throw new MissingCharError([',', '}'], state.lastIndex);
+ }
+ }
+
+ state.lastIndex++;
+ eatWhitespace(state);
+ state.value = object;
+ } else if (text[state.lastIndex] === '[') {
+ // array
+ const array = [];
+ state.lastIndex++;
+ eatWhitespace(state);
+ while (text[state.lastIndex] !== ']') {
+ parseJSONValue(state);
+ array.push(state.value);
+ if (text[state.lastIndex] === ',') {
+ state.lastIndex++;
+ eatWhitespace(state);
+ } else if (text[state.lastIndex] !== ']') {
+ throw new MissingCharError([',', ']'], state.lastIndex);
+ }
+ }
+
+ state.lastIndex++;
+ eatWhitespace(state);
+ state.value = array;
+ } else if (text[state.lastIndex] === '"' || text[state.lastIndex] === "'" || text[state.lastIndex] === '`') {
+ // string
+ parseString(state);
+ } else if (/[-\d.]/.test(text[state.lastIndex])) {
+ // number
+ parseNumber(state);
+ } else {
+ parseWord(state);
+ if (!(state.value in JSON_PRIME)) {
+ throw new ParseError({
+ code: 'unknownJSONLiteral',
+ args: [state.value],
+ message: `Unknown literal '${state.value}'`,
+ index: state.index
+ });
+ }
+
+ state.value = JSON_PRIME[state.value];
+ }
+ }
+
+ function parseNumber(state) {
+ const pos = state.lastIndex;
+ RX_NUMBER.lastIndex = pos;
+ const match = RX_NUMBER.exec(state.text);
+ if (!match) {
+ throw new ParseError({
+ code: 'invalidNumber',
+ message: 'Invalid number',
+ index: pos
+ });
+ }
+
+ state.index = pos;
+ state.value = Number(match[0].trim());
+ state.lastIndex += match[0].length;
+ }
+
+ function parseStringToEnd(state) {
+ RX_LINE.lastIndex = state.lastIndex;
+ const match = RX_LINE.exec(state.text);
+ const value = match[0].trim();
+ if (!value) {
+ throw new ParseError({
+ code: 'missingValue',
+ message: 'Missing value',
+ index: RX_LINE.lastIndex
+ });
+ }
+
+ state.index = state.lastIndex;
+ state.value = unquote(value);
+ state.lastIndex = RX_LINE.lastIndex;
+ }
+
+ function isValidVersion(version) {
+ return RX_VERSION.test(version);
+ }
+
+ var parseUtil = {
+ __proto__: null,
+ eatLine: eatLine,
+ eatWhitespace: eatWhitespace,
+ parseChar: parseChar,
+ parseEOT: parseEOT,
+ parseJSON: parseJSON,
+ parseNumber: parseNumber,
+ parseString: parseString,
+ parseStringToEnd: parseStringToEnd,
+ parseStringUnquoted: parseStringUnquoted,
+ parseWord: parseWord,
+ unquote: unquote,
+ isValidVersion: isValidVersion
+ };
+
+ /* eslint-env browser */
+
+ // eslint-disable-next-line node/no-unsupported-features/node-builtins
+ const _export_URL_ = self.URL;
+
+ var UNITS = ['em', 'ex', 'cap', 'ch', 'ic', 'rem', 'lh', 'rlh', 'vw', 'vh', 'vi', 'vb', 'vmin', 'vmax', 'cm', 'mm', 'Q', 'in', 'pt', 'pc', 'px', 'deg', 'grad', 'rad', 'turn', 's', 'ms', 'Hz', 'kHz', 'dpi', 'dpcm', 'dppx', '%'];
+
+ /**
+ * Gives you a array with filled with 0...amount - 1.
+ * @param {number} amount
+ * @returns {number[]}
+ */
+ function range(amount) {
+ const range = Array(amount);
+ for (let i = 0; i < amount; i++) {
+ range[i] = i;
+ }
+
+ return range;
+ }
+
+ /**
+ * Check if the amount of edits between firstString and secondString is <= maxEdits.
+ * It uses the Levenshtein distance algorithm with the two matrix rows variant.
+ * @param {string} firstString First string to be checked against the other string
+ * @param {string} secondString Second string to be checked against the other string
+ * @param {number} maxEdit The maximum amount of edits that these 2 string should have.
+ * @returns {boolean} indicate if the 2 strings's edits are less or equal to maxEdits
+ */
+ function LevenshteinDistanceWithMax(firstString, secondString, maxEdit) {
+ const lenOne = firstString.length;
+ const lenTwo = secondString.length;
+
+ const lenDiff = Math.abs(lenOne - lenTwo);
+ // Are the difference between 2 lengths greater than
+ // maxEdit, we know to bail out early on.
+ if (lenDiff > maxEdit) {
+ return false;
+ }
+
+ let prevRowDistance = range(lenOne + 1);
+ let currentRowDistance = Array(lenOne + 1);
+ for (let i = 1; i <= lenTwo; i++) {
+ // Calculate the current row distances from the previous row.
+ currentRowDistance[0] = i;
+ let minDistance = i;
+ for (let j = 1; j <= lenOne; j++) {
+ const editCost = firstString[j - 1] === secondString[i - 1] ? 0 : 1;
+
+ const addCost = prevRowDistance[j] + 1;
+ const delCost = currentRowDistance[j - 1] + 1;
+ const substitionCost = prevRowDistance[j - 1] + editCost;
+
+ currentRowDistance[j] = Math.min(addCost, delCost, substitionCost);
+ if (currentRowDistance[j] < minDistance) {
+ minDistance = currentRowDistance[j];
+ }
+ }
+
+ if (minDistance > maxEdit) {
+ return false;
+ }
+
+ // Swap the vectors
+ const vtemp = currentRowDistance;
+ currentRowDistance = prevRowDistance;
+ prevRowDistance = vtemp;
+ }
+
+ return prevRowDistance[lenOne] <= maxEdit;
+ }
+
+ const UNITS_SET = new Set(UNITS);
+
+ const DEFAULT_PARSER = {
+ name: parseStringToEnd,
+ version: parseStringToEnd,
+ namespace: parseStringToEnd,
+ author: parseStringToEnd,
+ description: parseStringToEnd,
+ homepageURL: parseStringToEnd,
+ supportURL: parseStringToEnd,
+ updateURL: parseStringToEnd,
+ license: parseStringToEnd,
+ preprocessor: parseStringToEnd
+ };
+
+ const DEFAULT_VALIDATOR = {
+ version: validateVersion,
+ homepageURL: validateURL,
+ supportURL: validateURL,
+ updateURL: validateURL
+ };
+
+ const DEFAULT_VAR_PARSER = {
+ text: parseStringToEnd,
+ color: parseStringToEnd,
+ checkbox: parseChar,
+ select: parseSelect,
+ dropdown: {
+ advanced: parseVarXStyle
+ },
+ image: {
+ var: parseSelect,
+ advanced: parseVarXStyle
+ },
+ number: parseRange,
+ range: parseRange
+ };
+
+ const DEFAULT_VAR_VALIDATOR = {
+ checkbox: validateCheckbox,
+ number: validateRange,
+ range: validateRange
+ };
+
+ const MANDATORY_META = ['name', 'namespace', 'version'];
+ const RANGE_PROPS = ['default', 'min', 'max', 'step'];
+
+ function parseRange(state) {
+ parseJSON(state);
+ const result = {
+ min: null,
+ max: null,
+ step: null,
+ units: null
+ };
+ if (typeof state.value === 'number') {
+ result.default = state.value;
+ } else if (Array.isArray(state.value)) {
+ let i = 0;
+ for (const item of state.value) {
+ if (typeof item === 'string') {
+ if (result.units != null) {
+ throw new ParseError({
+ code: 'invalidRangeMultipleUnits',
+ message: 'units is alredy defined',
+ args: [state.type],
+ index: state.valueIndex
+ });
+ }
+
+ result.units = item;
+ } else if (typeof item === 'number' || item === null) {
+ if (i >= RANGE_PROPS.length) {
+ throw new ParseError({
+ code: 'invalidRangeTooManyValues',
+ message: 'the array contains too many values',
+ args: [state.type],
+ index: state.valueIndex
+ });
+ }
+
+ result[RANGE_PROPS[i++]] = item;
+ } else {
+ throw new ParseError({
+ code: 'invalidRangeValue',
+ message: 'value must be number, string, or null',
+ args: [state.type],
+ index: state.valueIndex
+ });
+ }
+ }
+ } else {
+ throw new ParseError({
+ code: 'invalidRange',
+ message: 'the default value must be an array or a number',
+ index: state.valueIndex,
+ args: [state.type]
+ });
+ }
+
+ state.value = result.default;
+ Object.assign(state.varResult, result);
+ }
+
+ function parseSelect(state) {
+ parseJSON(state);
+ if (typeof state.value !== 'object' || !state.value) {
+ throw new ParseError({
+ code: 'invalidSelect',
+ message: 'The value must be an array or object'
+ });
+ }
+
+ const options = Array.isArray(state.value) ?
+ state.value.map(key => createOption(key)) :
+ Object.keys(state.value).map(key => createOption(key, state.value[key]));
+ if (new Set(options.map(o => o.name)).size < options.length) {
+ throw new ParseError({
+ code: 'invalidSelectNameDuplicated',
+ message: 'Option name is duplicated'
+ });
+ }
+
+ if (options.length === 0) {
+ throw new ParseError({
+ code: 'invalidSelectEmptyOptions',
+ message: 'Option list is empty'
+ });
+ }
+
+ const defaults = options.filter(o => o.isDefault);
+ if (defaults.length > 1) {
+ throw new ParseError({
+ code: 'invalidSelectMultipleDefaults',
+ message: 'multiple default values'
+ });
+ }
+
+ options.forEach(o => {
+ delete o.isDefault;
+ });
+ state.varResult.options = options;
+ state.value = (defaults.length > 0 ? defaults[0] : options[0]).name;
+ }
+
+ function parseVarXStyle(state) {
+ const pos = state.lastIndex;
+ if (state.text[state.lastIndex] !== '{') {
+ throw new MissingCharError(['{'], pos);
+ }
+
+ const options = [];
+ state.lastIndex++;
+ while (state.text[state.lastIndex] !== '}') {
+ const option = {};
+
+ parseStringUnquoted(state);
+ option.name = state.value;
+
+ parseString(state);
+ option.label = state.value;
+
+ if (state.type === 'dropdown') {
+ parseEOT(state);
+ } else {
+ parseString(state);
+ }
+
+ option.value = state.value;
+
+ options.push(option);
+ }
+
+ state.lastIndex++;
+ eatWhitespace(state);
+ if (options.length === 0) {
+ throw new ParseError({
+ code: 'invalidSelectEmptyOptions',
+ message: 'Option list is empty',
+ index: pos
+ });
+ }
+
+ if (state.type === 'dropdown') {
+ state.varResult.type = 'select';
+ state.type = 'select';
+ }
+
+ state.varResult.options = options;
+ state.value = options[0].name;
+ }
+
+ function createOption(label, value) {
+ if (typeof label !== 'string' || value && typeof value !== 'string') {
+ throw new ParseError({
+ code: 'invalidSelectValue',
+ message: 'Values in the object/array must be strings'
+ });
+ }
+
+ let isDefault = false;
+ if (label.endsWith('*')) {
+ isDefault = true;
+ label = label.slice(0, -1);
+ }
+
+ let name;
+ const match = label.match(/^(\w+):(.*)/);
+ if (match) {
+ ([, name, label] = match);
+ }
+
+ if (!name) {
+ name = label;
+ }
+
+ if (!label) {
+ throw new ParseError({
+ code: 'invalidSelectLabel',
+ message: 'Option label is empty'
+ });
+ }
+
+ if (value == null) {
+ value = name;
+ }
+
+ return {name, label, value, isDefault};
+ }
+
+ function collectErrors(fn, errors) {
+ if (errors) {
+ try {
+ fn();
+ } catch (err) {
+ errors.push(err);
+ }
+ } else {
+ fn();
+ }
+ }
+
+ function validateVersion(state) {
+ if (!isValidVersion(state.value)) {
+ throw new ParseError({
+ code: 'invalidVersion',
+ args: [state.value],
+ message: `Invalid version: ${state.value}`,
+ index: state.valueIndex
+ });
+ }
+
+ state.value = normalizeVersion(state.value);
+ }
+
+ function validateURL(state) {
+ let url;
+ try {
+ url = new _export_URL_(state.value);
+ } catch (err) {
+ err.args = [state.value];
+ err.index = state.valueIndex;
+ throw err;
+ }
+
+ if (!/^https?:/.test(url.protocol)) {
+ throw new ParseError({
+ code: 'invalidURLProtocol',
+ args: [url.protocol],
+ message: `Invalid protocol: ${url.protocol}`,
+ index: state.valueIndex
+ });
+ }
+ }
+
+ function validateCheckbox(state) {
+ if (state.value !== '1' && state.value !== '0') {
+ throw new ParseError({
+ code: 'invalidCheckboxDefault',
+ message: 'value must be 0 or 1',
+ index: state.valueIndex
+ });
+ }
+ }
+
+ function validateRange(state) {
+ const value = state.value;
+ if (typeof value !== 'number') {
+ throw new ParseError({
+ code: 'invalidRangeDefault',
+ message: `the default value of @var ${state.type} must be a number`,
+ index: state.valueIndex,
+ args: [state.type]
+ });
+ }
+
+ const result = state.varResult;
+ if (result.min != null && value < result.min) {
+ throw new ParseError({
+ code: 'invalidRangeMin',
+ message: 'the value is smaller than the minimum',
+ index: state.valueIndex,
+ args: [state.type]
+ });
+ }
+
+ if (result.max != null && value > result.max) {
+ throw new ParseError({
+ code: 'invalidRangeMax',
+ message: 'the value is larger than the maximum',
+ index: state.valueIndex,
+ args: [state.type]
+ });
+ }
+
+ if (
+ result.step != null &&
+ [value, result.min, result.max]
+ .some(n => n != null && !isMultipleOf(n, result.step))
+ ) {
+ throw new ParseError({
+ code: 'invalidRangeStep',
+ message: 'the value is not a multiple of the step',
+ index: state.valueIndex,
+ args: [state.type]
+ });
+ }
+
+ if (result.units && !UNITS_SET.has(result.units)) {
+ throw new ParseError({
+ code: 'invalidRangeUnits',
+ message: `Invalid CSS unit: ${result.units}`,
+ index: state.valueIndex,
+ args: [state.type, result.units]
+ });
+ }
+ }
+
+ function isMultipleOf(value, step) {
+ const n = Math.abs(value / step);
+ const nInt = Math.round(n);
+ // IEEE 754 double-precision numbers can reliably store 15 decimal digits
+ // of which some are already occupied by the integer part
+ return Math.abs(n - nInt) < Math.pow(10, (`${nInt}`.length - 16));
+ }
+
+ function createParser({
+ unknownKey = 'ignore',
+ mandatoryKeys = MANDATORY_META,
+ parseKey: userParseKey,
+ parseVar: userParseVar,
+ validateKey: userValidateKey,
+ validateVar: userValidateVar,
+ allowErrors = false
+ } = {}) {
+ if (!['ignore', 'assign', 'throw'].includes(unknownKey)) {
+ throw new TypeError("unknownKey must be 'ignore', 'assign', or 'throw'");
+ }
+
+ const parser = Object.assign(Object.create(null), DEFAULT_PARSER, userParseKey);
+ const keysOfParser = [...Object.keys(parser), 'advanced', 'var'];
+ const varParser = Object.assign({}, DEFAULT_VAR_PARSER, userParseVar);
+ const validator = Object.assign({}, DEFAULT_VALIDATOR, userValidateKey);
+ const varValidator = Object.assign({}, DEFAULT_VAR_VALIDATOR, userValidateVar);
+
+ return {parse, validateVar};
+
+ function validateVar(varObject) {
+ const state = {
+ key: 'var',
+ type: varObject.type,
+ value: varObject.value,
+ varResult: varObject
+ };
+ _validateVar(state);
+ }
+
+ function _validateVar(state) {
+ const validate = typeof varValidator[state.type] === 'object' ?
+ varValidator[state.type][state.key] : varValidator[state.type];
+ if (validate) {
+ validate(state);
+ }
+ }
+
+ function parseVar(state) {
+ const result = {
+ type: null,
+ label: null,
+ name: null,
+ value: null,
+ default: null,
+ options: null
+ };
+ state.varResult = result;
+
+ parseWord(state);
+ state.type = state.value;
+ result.type = state.type;
+
+ const doParse = typeof varParser[state.type] === 'object' ?
+ varParser[state.type][state.key] : varParser[state.type];
+ if (!doParse) {
+ throw new ParseError({
+ code: 'unknownVarType',
+ message: `Unknown @${state.key} type: ${state.type}`,
+ args: [state.key, state.type],
+ index: state.index
+ });
+ }
+
+ parseWord(state);
+ result.name = state.value;
+
+ parseString(state, true);
+ result.label = state.value;
+
+ state.valueIndex = state.lastIndex;
+ doParse(state);
+ _validateVar(state);
+ result.default = state.value;
+ if (!state.usercssData.vars) {
+ state.usercssData.vars = {};
+ }
+
+ state.usercssData.vars[result.name] = result;
+ if (state.key === 'advanced') {
+ state.maybeUSO = true;
+ }
+ }
+
+ function parse(text) {
+ if (text.includes('\r')) {
+ throw new TypeError("metadata includes invalid character: '\\r'");
+ }
+
+ const usercssData = {};
+ const errors = [];
+
+ const re = /@([\w-]+)[^\S\r\n]*/gm;
+ const state = {
+ index: 0,
+ lastIndex: 0,
+ text,
+ usercssData,
+ warn: err => errors.push(err)
+ };
+
+ // parse
+ let match;
+ while ((match = re.exec(text))) {
+ state.index = match.index;
+ state.lastIndex = re.lastIndex;
+ state.key = match[1];
+ state.shouldIgnore = false;
+
+ collectErrors(() => {
+ try {
+ if (state.key === 'var' || state.key === 'advanced') {
+ parseVar(state);
+ } else {
+ parseKey(state);
+ }
+ } catch (err) {
+ if (err.index === undefined) {
+ err.index = state.index;
+ }
+
+ throw err;
+ }
+
+ if (state.key !== 'var' && state.key !== 'advanced' && !state.shouldIgnore) {
+ usercssData[state.key] = state.value;
+ }
+ }, allowErrors && errors);
+
+ re.lastIndex = state.lastIndex;
+ }
+
+ if (state.maybeUSO && !usercssData.preprocessor) {
+ usercssData.preprocessor = 'uso';
+ }
+
+ collectErrors(() => {
+ const missing = mandatoryKeys.filter(k =>
+ !Object.prototype.hasOwnProperty.call(usercssData, k) || !usercssData[k]
+ );
+ if (missing.length > 0) {
+ throw new ParseError({
+ code: 'missingMandatory',
+ args: missing,
+ message: `Missing metadata: ${missing.map(k => `@${k}`).join(', ')}`
+ });
+ }
+ }, allowErrors && errors);
+
+ return {
+ metadata: usercssData,
+ errors
+ };
+ }
+
+ function parseKey(state) {
+ let doParse = parser[state.key];
+ if (!doParse) {
+ if (unknownKey === 'assign') {
+ doParse = parseStringToEnd;
+ } else {
+ eatLine(state);
+ if (unknownKey === 'ignore') {
+ state.shouldIgnore = true;
+ return;
+ }
+
+ // TODO: Suggest the item with the smallest distance or even multiple results?
+ // Implementation note: swtich to Levenshtein automaton variation.
+ const MAX_EDIT = Math.log2(state.key.length);
+ const maybeSuggestion = keysOfParser.find(metaKey => LevenshteinDistanceWithMax(metaKey, state.key, MAX_EDIT));
+
+ // throw
+ throw new ParseError({
+ code: 'unknownMeta',
+ args: [state.key, maybeSuggestion],
+ message: `Unknown metadata: @${state.key}${maybeSuggestion ? `, did you mean @${maybeSuggestion}?` : ''}`,
+ index: state.index
+ });
+ }
+ }
+
+ state.valueIndex = state.lastIndex;
+ doParse(state);
+ if (validator[state.key]) {
+ validator[state.key](state);
+ }
+ }
+ }
+
+ function normalizeVersion(version) {
+ // https://docs.npmjs.com/misc/semver#versions
+ if (version[0] === 'v' || version[0] === '=') {
+ return version.slice(1);
+ }
+
+ return version;
+ }
+
+ const _export_parse_ = function (text, options) {
+ return createParser(options).parse(text);
+ };
+
+ function createStringifier({
+ alignKeys = false,
+ space = 2,
+ format = 'stylus',
+ stringifyKey: userStringifyKey = {},
+ stringifyVar: userStringifyVar = {}
+ } = {}) {
+ function stringify(meta) {
+ let varKey;
+ if (format === 'stylus') {
+ varKey = 'var';
+ } else if (format === 'xstyle') {
+ varKey = 'advanced';
+ } else {
+ throw new TypeError("options.format must be 'stylus' or 'xstyle'");
+ }
+
+ const lines = [];
+ for (const key of Object.keys(meta)) {
+ const value = meta[key];
+ if (Object.prototype.hasOwnProperty.call(userStringifyKey, key)) {
+ const result = userStringifyKey[key](value);
+ if (Array.isArray(result)) {
+ lines.push.apply(lines, result.map(v => [key, v]));
+ } else {
+ lines.push([key, result]);
+ }
+ } else if (key === 'vars') {
+ for (const va of Object.values(value)) {
+ lines.push([varKey, stringifyVar(va, format, userStringifyVar, space)]);
+ }
+ } else if (Array.isArray(value)) {
+ for (const subLine of value) {
+ lines.push([key, quoteIfNeeded(subLine)]);
+ }
+ } else {
+ lines.push([key, quoteIfNeeded(value)]);
+ }
+ }
+
+ const maxKeyLength = alignKeys ? Math.max.apply(null, lines.map(l => l[0].length)) : 0;
+ return `/* ==UserStyle==\n${
+ escapeComment(lines.map(([key, text]) => `@${key.padEnd(maxKeyLength)} ${text}`).join('\n'))
+ }\n==/UserStyle== */`;
+ }
+
+ return {stringify};
+ }
+
+ function stringifyVar(va, format, userStringifyVar, space) {
+ return `${vaType()} ${va.name} ${JSON.stringify(va.label)} ${vaDefault()}`;
+
+ function vaType() {
+ if (format === 'xstyle' && va.type === 'select') {
+ return 'dropdown';
+ }
+
+ return va.type;
+ }
+
+ function vaDefault() {
+ if (Object.prototype.hasOwnProperty.call(userStringifyVar, va.type)) {
+ return userStringifyVar[va.type](va, format, space);
+ }
+
+ if (va.options) {
+ if (format === 'stylus') {
+ return JSON.stringify(va.options.reduce((object, opt) => {
+ const isDefault = opt.name === va.default ? '*' : '';
+ object[`${opt.name}:${opt.label}${isDefault}`] = opt.value;
+ return object;
+ }, {}), null, space);
+ }
+
+ return stringifyEOT(va.options, va.type === 'image', space);
+ }
+
+ if (va.type === 'text' && format === 'xstyle') {
+ return JSON.stringify(va.default);
+ }
+
+ if (va.type === 'number' || va.type === 'range') {
+ const output = [va.default, va.min, va.max, va.step];
+ if (va.units) {
+ output.push(va.units);
+ }
+
+ return JSON.stringify(output);
+ }
+
+ return va.default;
+ }
+ }
+
+ function quoteIfNeeded(text) {
+ if (typeof text === 'string' && text.includes('\n')) {
+ return JSON.stringify(text);
+ }
+
+ return text;
+ }
+
+ function escapeComment(text) {
+ return text.replace(/\*\//g, '*\\/');
+ }
+
+ function stringifyEOT(options, singleLine = false, space = 0) {
+ const pad = typeof space === 'string' ? space : ' '.repeat(space);
+ return `{\n${options.map(
+ o => `${pad}${o.name} ${JSON.stringify(o.label)} ${oValue(o.value)}`
+ ).join('\n')}\n}`;
+
+ function oValue(value) {
+ if (singleLine) {
+ return JSON.stringify(value);
+ }
+
+ return `<<`'${e}'`)).join(", ")}`,index:n})}}class a extends n{constructor(e){super({code:"EOF",message:"Unexpected end of file",index:e})}}const s=/<<e[1]===n?n:JSON.parse(`"${e}"`)))}function g(e){l.lastIndex=e.lastIndex,l.exec(e.text),e.lastIndex=l.lastIndex}function m(e){i.lastIndex=e.lastIndex,e.lastIndex+=i.exec(e.text)[0].length}function h(e){if(e.lastIndex>=e.text.length)throw new a(e.lastIndex);e.index=e.lastIndex,e.value=e.text[e.lastIndex],e.lastIndex++,m(e)}function w(e){const t=e.lastIndex;u.lastIndex=t;const a=u.exec(e.text);if(!a)throw new n({code:"invalidWord",message:"Invalid word",index:t});e.index=t,e.value=a[1],e.lastIndex+=a[0].length}function I(e){const n=e.lastIndex;try{$(e)}catch(e){throw e.message=`Invalid JSON: ${e.message}`,e}e.index=n}function b(e){const t=e.lastIndex;s.lastIndex=t;const a=s.exec(e.text);if(!a)throw new n({code:"missingEOT",message:"Missing EOT",index:t});e.index=t,e.lastIndex+=a[0].length,e.value=v(a[1].trim()),m(e)}function O(e){x.lastIndex=e.lastIndex;const n=x.exec(e.text);e.index=e.lastIndex,e.lastIndex=x.lastIndex,e.value=n[0].trim().replace(/\s+/g,"-")}function S(e,t=!1){const a=e.lastIndex,s="`"===e.text[a]?d:c;s.lastIndex=a;const l=s.exec(e.text);if(!l)throw new n({code:"invalidString",message:"Invalid string",index:a});e.index=a,e.lastIndex+=l[0].length,e.value=y(l[1]),t?function(e){o.lastIndex=e.lastIndex,e.lastIndex+=o.exec(e.text)[0].length}(e):m(e)}function $(e){const{text:a}=e;if("{"===a[e.lastIndex]){const n={};for(e.lastIndex++,m(e);"}"!==a[e.lastIndex];){S(e);const s=e.value;if(":"!==a[e.lastIndex])throw new t([":"],e.lastIndex);if(e.lastIndex++,m(e),$(e),n[s]=e.value,","===a[e.lastIndex])e.lastIndex++,m(e);else if("}"!==a[e.lastIndex])throw new t([",","}"],e.lastIndex)}e.lastIndex++,m(e),e.value=n}else if("["===a[e.lastIndex]){const n=[];for(e.lastIndex++,m(e);"]"!==a[e.lastIndex];)if($(e),n.push(e.value),","===a[e.lastIndex])e.lastIndex++,m(e);else if("]"!==a[e.lastIndex])throw new t([",","]"],e.lastIndex);e.lastIndex++,m(e),e.value=n}else if('"'===a[e.lastIndex]||"'"===a[e.lastIndex]||"`"===a[e.lastIndex])S(e);else if(/[-\d.]/.test(a[e.lastIndex]))k(e);else{if(w(e),!(e.value in f))throw new n({code:"unknownJSONLiteral",args:[e.value],message:`Unknown literal '${e.value}'`,index:e.index});e.value=f[e.value]}}function k(e){const t=e.lastIndex;r.lastIndex=t;const a=r.exec(e.text);if(!a)throw new n({code:"invalidNumber",message:"Invalid number",index:t});e.index=t,e.value=Number(a[0].trim()),e.lastIndex+=a[0].length}function R(e){l.lastIndex=e.lastIndex;const t=l.exec(e.text)[0].trim();if(!t)throw new n({code:"missingValue",message:"Missing value",index:l.lastIndex});e.index=e.lastIndex,e.value=y(t),e.lastIndex=l.lastIndex}function j(e){return p.test(e)}var E={__proto__:null,eatLine:g,eatWhitespace:m,parseChar:h,parseEOT:b,parseJSON:I,parseNumber:k,parseString:S,parseStringToEnd:R,parseStringUnquoted:O,parseWord:w,unquote:y,isValidVersion:j};const M=self.URL,U=new Set(["em","ex","cap","ch","ic","rem","lh","rlh","vw","vh","vi","vb","vmin","vmax","cm","mm","Q","in","pt","pc","px","deg","grad","rad","turn","s","ms","Hz","kHz","dpi","dpcm","dppx","%"]),N={name:R,version:R,namespace:R,author:R,description:R,homepageURL:R,supportURL:R,updateURL:R,license:R,preprocessor:R},T={version:function(e){if(!j(e.value))throw new n({code:"invalidVersion",args:[e.value],message:`Invalid version: ${e.value}`,index:e.valueIndex});var t;e.value="v"===(t=e.value)[0]||"="===t[0]?t.slice(1):t},homepageURL:W,supportURL:W,updateURL:W},V={text:R,color:R,checkbox:h,select:_,dropdown:{advanced:P},image:{var:_,advanced:P},number:L,range:L},A={checkbox:function(e){if("1"!==e.value&&"0"!==e.value)throw new n({code:"invalidCheckboxDefault",message:"value must be 0 or 1",index:e.valueIndex})},number:z,range:z},D=["name","namespace","version"],J=["default","min","max","step"];function L(e){I(e);const t={min:null,max:null,step:null,units:null};if("number"==typeof e.value)t.default=e.value;else{if(!Array.isArray(e.value))throw new n({code:"invalidRange",message:"the default value must be an array or a number",index:e.valueIndex,args:[e.type]});{let a=0;for(const s of e.value)if("string"==typeof s){if(null!=t.units)throw new n({code:"invalidRangeMultipleUnits",message:"units is alredy defined",args:[e.type],index:e.valueIndex});t.units=s}else{if("number"!=typeof s&&null!==s)throw new n({code:"invalidRangeValue",message:"value must be number, string, or null",args:[e.type],index:e.valueIndex});if(a>=J.length)throw new n({code:"invalidRangeTooManyValues",message:"the array contains too many values",args:[e.type],index:e.valueIndex});t[J[a++]]=s}}}e.value=t.default,Object.assign(e.varResult,t)}function _(e){if(I(e),"object"!=typeof e.value||!e.value)throw new n({code:"invalidSelect",message:"The value must be an array or object"});const t=Array.isArray(e.value)?e.value.map((e=>K(e))):Object.keys(e.value).map((n=>K(n,e.value[n])));if(new Set(t.map((e=>e.name))).sizee.isDefault));if(a.length>1)throw new n({code:"invalidSelectMultipleDefaults",message:"multiple default values"});t.forEach((e=>{delete e.isDefault})),e.varResult.options=t,e.value=(a.length>0?a[0]:t[0]).name}function P(e){const a=e.lastIndex;if("{"!==e.text[e.lastIndex])throw new t(["{"],a);const s=[];for(e.lastIndex++;"}"!==e.text[e.lastIndex];){const n={};O(e),n.name=e.value,S(e),n.label=e.value,"dropdown"===e.type?b(e):S(e),n.value=e.value,s.push(n)}if(e.lastIndex++,m(e),0===s.length)throw new n({code:"invalidSelectEmptyOptions",message:"Option list is empty",index:a});"dropdown"===e.type&&(e.varResult.type="select",e.type="select"),e.varResult.options=s,e.value=s[0].name}function K(e,t){if("string"!=typeof e||t&&"string"!=typeof t)throw new n({code:"invalidSelectValue",message:"Values in the object/array must be strings"});let a,s=!1;e.endsWith("*")&&(s=!0,e=e.slice(0,-1));const l=e.match(/^(\w+):(.*)/);if(l&&([,a,e]=l),a||(a=e),!e)throw new n({code:"invalidSelectLabel",message:"Option label is empty"});return null==t&&(t=a),{name:a,label:e,value:t,isDefault:s}}function C(e,n){if(n)try{e()}catch(e){n.push(e)}else e()}function W(e){let t;try{t=new M(e.value)}catch(n){throw n.args=[e.value],n.index=e.valueIndex,n}if(!/^https?:/.test(t.protocol))throw new n({code:"invalidURLProtocol",args:[t.protocol],message:`Invalid protocol: ${t.protocol}`,index:e.valueIndex})}function z(e){const t=e.value;if("number"!=typeof t)throw new n({code:"invalidRangeDefault",message:`the default value of @var ${e.type} must be a number`,index:e.valueIndex,args:[e.type]});const a=e.varResult;if(null!=a.min&&ta.max)throw new n({code:"invalidRangeMax",message:"the value is larger than the maximum",index:e.valueIndex,args:[e.type]});if(null!=a.step&&[t,a.min,a.max].some((e=>null!=e&&!function(e,n){const t=Math.abs(e/n),a=Math.round(t);return Math.abs(t-a)s.push(e)};let o;for(;o=l.exec(e);)r.index=o.index,r.lastIndex=l.lastIndex,r.key=o[1],r.shouldIgnore=!1,C((()=>{try{"var"===r.key||"advanced"===r.key?f(r):v(r)}catch(e){throw void 0===e.index&&(e.index=r.index),e}"var"===r.key||"advanced"===r.key||r.shouldIgnore||(a[r.key]=r.value)}),i&&s),l.lastIndex=r.lastIndex;return r.maybeUSO&&!a.preprocessor&&(a.preprocessor="uso"),C((()=>{const e=t.filter((e=>!Object.prototype.hasOwnProperty.call(a,e)||!a[e]));if(e.length>0)throw new n({code:"missingMandatory",args:e,message:`Missing metadata: ${e.map((e=>`@${e}`)).join(", ")}`})}),i&&s),{metadata:a,errors:s}},validateVar:function(e){p({key:"var",type:e.type,value:e.value,varResult:e})}};function p(e){const n="object"==typeof x[e.type]?x[e.type][e.key]:x[e.type];n&&n(e)}function f(e){const t={type:null,label:null,name:null,value:null,default:null,options:null};e.varResult=t,w(e),e.type=e.value,t.type=e.type;const a="object"==typeof d[e.type]?d[e.type][e.key]:d[e.type];if(!a)throw new n({code:"unknownVarType",message:`Unknown @${e.key} type: ${e.type}`,args:[e.key,e.type],index:e.index});w(e),t.name=e.value,S(e,!0),t.label=e.value,e.valueIndex=e.lastIndex,a(e),p(e),t.default=e.value,e.usercssData.vars||(e.usercssData.vars={}),e.usercssData.vars[t.name]=t,"advanced"===e.key&&(e.maybeUSO=!0)}function v(t){let a=o[t.key];if(!a){if("assign"!==e){if(g(t),"ignore"===e)return void(t.shouldIgnore=!0);const a=Math.log2(t.key.length),s=u.find((e=>function(e,n,t){const a=e.length,s=n.length;if(Math.abs(a-s)>t)return!1;let l=function(e){const n=Array(e);for(let t=0;tt)return!1;const o=r;r=l,l=o}return l[a]<=t}(e,t.key,a)));throw new n({code:"unknownMeta",args:[t.key,s],message:`Unknown metadata: @${t.key}${s?`, did you mean @${s}?`:""}`,index:t.index})}a=R}t.valueIndex=t.lastIndex,a(t),c[t.key]&&c[t.key](t)}}function F({alignKeys:e=!1,space:n=2,format:t="stylus",stringifyKey:a={},stringifyVar:s={}}={}){return{stringify:function(l){let r;if("stylus"===t)r="var";else{if("xstyle"!==t)throw new TypeError("options.format must be 'stylus' or 'xstyle'");r="advanced"}const i=[];for(const e of Object.keys(l)){const o=l[e];if(Object.prototype.hasOwnProperty.call(a,e)){const n=a[e](o);Array.isArray(n)?i.push.apply(i,n.map((n=>[e,n]))):i.push([e,n])}else if("vars"===e)for(const e of Object.values(o))i.push([r,H(e,t,s,n)]);else if(Array.isArray(o))for(const n of o)i.push([e,Q(n)]);else i.push([e,Q(o)])}const o=e?Math.max.apply(null,i.map((e=>e[0].length))):0;return`/* ==UserStyle==\n${u=i.map((([e,n])=>`@${e.padEnd(o)} ${n}`)).join("\n"),u.replace(/\*\//g,"*\\/")}\n==/UserStyle== */`;var u}}}function H(e,n,t,a){return`${"xstyle"===n&&"select"===e.type?"dropdown":e.type} ${e.name} ${JSON.stringify(e.label)} ${function(){if(Object.prototype.hasOwnProperty.call(t,e.type))return t[e.type](e,n,a);if(e.options)return"stylus"===n?JSON.stringify(e.options.reduce(((n,t)=>{const a=t.name===e.default?"*":"";return n[`${t.name}:${t.label}${a}`]=t.value,n}),{}),null,a):function(e,n=!1,t=0){const a="string"==typeof t?t:" ".repeat(t);return`{\n${e.map((e=>{return`${a}${e.name} ${JSON.stringify(e.label)} ${t=e.value,n?JSON.stringify(t):`<< {
+ o.resolve = resolve;
+ o.reject = reject;
+ });
+ return o;
+ }
+
+ function launchWebAuthFlow(_x8) {
+ return _launchWebAuthFlow.apply(this, arguments);
+ }
+
+ function _launchWebAuthFlow() {
+ _launchWebAuthFlow = _asyncToGenerator(function* ({
+ url,
+ redirect_uri,
+ interactive = false,
+ alwaysUseTab = false,
+ windowOptions
+ }) {
+ const wInfo = yield createWindow(_objectSpread2({
+ type: "popup",
+ url,
+ state: "minimized"
+ }, windowOptions), alwaysUseTab);
+ const windowId = wInfo.id;
+ const tabId = wInfo.tabs[0].id;
+
+ const _defer = defer(),
+ promise = _defer.promise,
+ resolve = _defer.resolve,
+ reject = _defer.reject;
+
+ browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, {
+ urls: ["*://*/*"],
+ tabId,
+ types: ["main_frame"]
+ }, ["blocking"]);
+ browser.webNavigation.onDOMContentLoaded.addListener(onDOMContentLoaded);
+ browser.tabs.onRemoved.addListener(onTabRemoved);
+
+ try {
+ return yield promise;
+ } finally {
+ cleanup();
+ }
+
+ function onBeforeRequest(details) {
+ if (details.frameId || details.tabId !== tabId) return;
+ if (!details.url.startsWith(redirect_uri)) return;
+ resolve(details.url);
+ return {
+ cancel: true
+ };
+ }
+
+ function onDOMContentLoaded(details) {
+ if (details.frameId || details.tabId !== tabId) return;
+
+ if (interactive) {
+ updateWindow(windowId, tabId, {
+ focused: true,
+ state: "normal"
+ }).catch(err => console.error(err));
+ } else {
+ reject(new Error("User interaction required"));
+ }
+
+ browser.webNavigation.onDOMContentLoaded.removeListener(onDOMContentLoaded);
+ }
+
+ function onTabRemoved(removedTabId) {
+ if (removedTabId === tabId) {
+ reject(new Error("Canceled by user"));
+ }
+ }
+
+ function cleanup() {
+ browser.webRequest.onBeforeRequest.removeListener(onBeforeRequest);
+ browser.webNavigation.onDOMContentLoaded.removeListener(onDOMContentLoaded);
+ browser.tabs.onRemoved.removeListener(onTabRemoved);
+ closeWindow(windowId, tabId).catch(err => console.error(err));
+ }
+ });
+ return _launchWebAuthFlow.apply(this, arguments);
+ }
+
+ return launchWebAuthFlow;
+
+}());
diff --git a/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min.js b/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min.js
deleted file mode 100644
index 267634e7..00000000
--- a/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var webextLaunchWebAuthFlow=function(){"use strict";function e(e,r,t,n,o,i,s){try{var u=e[i](s),c=u.value}catch(e){return void t(e)}u.done?r(c):Promise.resolve(c).then(n,o)}function r(r){return function(){var t=this,n=arguments;return new Promise((function(o,i){var s=r.apply(t,n);function u(r){e(s,o,i,u,c,"next",r)}function c(r){e(s,o,i,u,c,"throw",r)}u(void 0)}))}}function t(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function n(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var r=1;r{e.resolve=r,e.reject=t}),e}function d(){return(d=r((function*({url:e,redirect_uri:r,interactive:t=!1,alwaysUseTab:n=!1,windowOptions:s}){const c=yield i(o({type:"popup",url:e,state:"minimized"},s),n),b=c.id,d=c.tabs[0].id,f=l(),p=f.promise,w=f.resolve,y=f.reject;browser.webRequest.onBeforeRequest.addListener(v,{urls:["*://*/*"],tabId:d,types:["main_frame"]},["blocking"]),browser.webNavigation.onDOMContentLoaded.addListener(m),browser.tabs.onRemoved.addListener(O);try{return yield p}finally{browser.webRequest.onBeforeRequest.removeListener(v),browser.webNavigation.onDOMContentLoaded.removeListener(m),browser.tabs.onRemoved.removeListener(O),a(b,d).catch(e=>console.error(e))}function v(e){if(!e.frameId&&e.tabId===d&&e.url.startsWith(r))return w(e.url),{cancel:!0}}function m(e){e.frameId||e.tabId!==d||(t?u(b,d,{focused:!0,state:"normal"}).catch(e=>console.error(e)):y(new Error("User interaction required")),browser.webNavigation.onDOMContentLoaded.removeListener(m))}function O(e){e===d&&y(new Error("Canceled by user"))}}))).apply(this,arguments)}return function(e){return d.apply(this,arguments)}}();
-//# sourceMappingURL=webext-launch-web-auth-flow.min.js.map