From 2efb6c5cd1e97739fdf06161c1e89e92aa06140c Mon Sep 17 00:00:00 2001 From: tophf Date: Thu, 31 Mar 2022 13:56:51 +0300 Subject: [PATCH] strip source mapping from vendor js --- background/sync-manager.js | 2 +- background/token-manager.js | 2 +- js/meta-parser.js | 2 +- manage/manage.js | 2 +- tools/build-vendor.js | 22 +- vendor/db-to-cloud/README.md | 2 +- vendor/db-to-cloud/db-to-cloud.js | 2262 +++++++++++++++++ vendor/db-to-cloud/db-to-cloud.min.js | 2 - vendor/draggable-list/README.md | 2 +- vendor/draggable-list/draggable-list.iife.js | 166 ++ .../draggable-list/draggable-list.iife.min.js | 1 - vendor/usercss-meta/README.md | 2 +- vendor/usercss-meta/usercss-meta.js | 1067 ++++++++ vendor/usercss-meta/usercss-meta.min.js | 2 - vendor/webext-launch-web-auth-flow/README.md | 2 +- .../webext-launch-web-auth-flow.js | 234 ++ .../webext-launch-web-auth-flow.min.js | 2 - 17 files changed, 3752 insertions(+), 22 deletions(-) create mode 100644 vendor/db-to-cloud/db-to-cloud.js delete mode 100644 vendor/db-to-cloud/db-to-cloud.min.js create mode 100644 vendor/draggable-list/draggable-list.iife.js delete mode 100644 vendor/draggable-list/draggable-list.iife.min.js create mode 100644 vendor/usercss-meta/usercss-meta.js delete mode 100644 vendor/usercss-meta/usercss-meta.min.js create mode 100644 vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.js delete mode 100644 vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min.js 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