From 580990a5eb4a79892c48e3a3fce3386fe80e6cc2 Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 2 Feb 2019 22:15:54 -0500 Subject: finish cache design --- build/background.js | 987 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 925 insertions(+), 62 deletions(-) (limited to 'build/background.js') diff --git a/build/background.js b/build/background.js index ec5d6af..7804de6 100644 --- a/build/background.js +++ b/build/background.js @@ -1,4 +1,728 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1 + +// lruList is a yallist where the head is the youngest +// item, and the tail is the oldest. the list contains the Hit +// objects as the entries. +// Each Hit object has a reference to its Yallist.Node. This +// never changes. +// +// cache is a Map (or PseudoMap) that matches the keys to +// the Yallist.Node object. +class LRUCache { + constructor (options) { + if (typeof options === 'number') + options = { max: options } + + if (!options) + options = {} + + if (options.max && (typeof options.max !== 'number' || options.max < 0)) + throw new TypeError('max must be a non-negative number') + // Kind of weird to have a default max of Infinity, but oh well. + const max = this[MAX] = options.max || Infinity + + const lc = options.length || naiveLength + this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc + this[ALLOW_STALE] = options.stale || false + if (options.maxAge && typeof options.maxAge !== 'number') + throw new TypeError('maxAge must be a number') + this[MAX_AGE] = options.maxAge || 0 + this[DISPOSE] = options.dispose + this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false + this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false + this.reset() + } + + // resize the cache when the max changes. + set max (mL) { + if (typeof mL !== 'number' || mL < 0) + throw new TypeError('max must be a non-negative number') + + this[MAX] = mL || Infinity + trim(this) + } + get max () { + return this[MAX] + } + + set allowStale (allowStale) { + this[ALLOW_STALE] = !!allowStale + } + get allowStale () { + return this[ALLOW_STALE] + } + + set maxAge (mA) { + if (typeof mA !== 'number') + throw new TypeError('maxAge must be a non-negative number') + + this[MAX_AGE] = mA + trim(this) + } + get maxAge () { + return this[MAX_AGE] + } + + // resize the cache when the lengthCalculator changes. + set lengthCalculator (lC) { + if (typeof lC !== 'function') + lC = naiveLength + + if (lC !== this[LENGTH_CALCULATOR]) { + this[LENGTH_CALCULATOR] = lC + this[LENGTH] = 0 + this[LRU_LIST].forEach(hit => { + hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) + this[LENGTH] += hit.length + }) + } + trim(this) + } + get lengthCalculator () { return this[LENGTH_CALCULATOR] } + + get length () { return this[LENGTH] } + get itemCount () { return this[LRU_LIST].length } + + rforEach (fn, thisp) { + thisp = thisp || this + for (let walker = this[LRU_LIST].tail; walker !== null;) { + const prev = walker.prev + forEachStep(this, fn, walker, thisp) + walker = prev + } + } + + forEach (fn, thisp) { + thisp = thisp || this + for (let walker = this[LRU_LIST].head; walker !== null;) { + const next = walker.next + forEachStep(this, fn, walker, thisp) + walker = next + } + } + + keys () { + return this[LRU_LIST].toArray().map(k => k.key) + } + + values () { + return this[LRU_LIST].toArray().map(k => k.value) + } + + reset () { + if (this[DISPOSE] && + this[LRU_LIST] && + this[LRU_LIST].length) { + this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) + } + + this[CACHE] = new Map() // hash of items by key + this[LRU_LIST] = new Yallist() // list of items in order of use recency + this[LENGTH] = 0 // length of items in the list + } + + dump () { + return this[LRU_LIST].map(hit => + isStale(this, hit) ? false : { + k: hit.key, + v: hit.value, + e: hit.now + (hit.maxAge || 0) + }).toArray().filter(h => h) + } + + dumpLru () { + return this[LRU_LIST] + } + + set (key, value, maxAge) { + maxAge = maxAge || this[MAX_AGE] + + if (maxAge && typeof maxAge !== 'number') + throw new TypeError('maxAge must be a number') + + const now = maxAge ? Date.now() : 0 + const len = this[LENGTH_CALCULATOR](value, key) + + if (this[CACHE].has(key)) { + if (len > this[MAX]) { + del(this, this[CACHE].get(key)) + return false + } + + const node = this[CACHE].get(key) + const item = node.value + + // dispose of the old one before overwriting + // split out into 2 ifs for better coverage tracking + if (this[DISPOSE]) { + if (!this[NO_DISPOSE_ON_SET]) + this[DISPOSE](key, item.value) + } + + item.now = now + item.maxAge = maxAge + item.value = value + this[LENGTH] += len - item.length + item.length = len + this.get(key) + trim(this) + return true + } + + const hit = new Entry(key, value, len, now, maxAge) + + // oversized objects fall out of cache automatically. + if (hit.length > this[MAX]) { + if (this[DISPOSE]) + this[DISPOSE](key, value) + + return false + } + + this[LENGTH] += hit.length + this[LRU_LIST].unshift(hit) + this[CACHE].set(key, this[LRU_LIST].head) + trim(this) + return true + } + + has (key) { + if (!this[CACHE].has(key)) return false + const hit = this[CACHE].get(key).value + return !isStale(this, hit) + } + + get (key) { + return get(this, key, true) + } + + peek (key) { + return get(this, key, false) + } + + pop () { + const node = this[LRU_LIST].tail + if (!node) + return null + + del(this, node) + return node.value + } + + del (key) { + del(this, this[CACHE].get(key)) + } + + load (arr) { + // reset the cache + this.reset() + + const now = Date.now() + // A previous serialized cache has the most recent items first + for (let l = arr.length - 1; l >= 0; l--) { + const hit = arr[l] + const expiresAt = hit.e || 0 + if (expiresAt === 0) + // the item was created without expiration in a non aged cache + this.set(hit.k, hit.v) + else { + const maxAge = expiresAt - now + // dont add already expired items + if (maxAge > 0) { + this.set(hit.k, hit.v, maxAge) + } + } + } + } + + prune () { + this[CACHE].forEach((value, key) => get(this, key, false)) + } +} + +const get = (self, key, doUse) => { + const node = self[CACHE].get(key) + if (node) { + const hit = node.value + if (isStale(self, hit)) { + del(self, node) + if (!self[ALLOW_STALE]) + return undefined + } else { + if (doUse) { + if (self[UPDATE_AGE_ON_GET]) + node.value.now = Date.now() + self[LRU_LIST].unshiftNode(node) + } + } + return hit.value + } +} + +const isStale = (self, hit) => { + if (!hit || (!hit.maxAge && !self[MAX_AGE])) + return false + + const diff = Date.now() - hit.now + return hit.maxAge ? diff > hit.maxAge + : self[MAX_AGE] && (diff > self[MAX_AGE]) +} + +const trim = self => { + if (self[LENGTH] > self[MAX]) { + for (let walker = self[LRU_LIST].tail; + self[LENGTH] > self[MAX] && walker !== null;) { + // We know that we're about to delete this one, and also + // what the next least recently used key will be, so just + // go ahead and set it now. + const prev = walker.prev + del(self, walker) + walker = prev + } + } +} + +const del = (self, node) => { + if (node) { + const hit = node.value + if (self[DISPOSE]) + self[DISPOSE](hit.key, hit.value) + + self[LENGTH] -= hit.length + self[CACHE].delete(hit.key) + self[LRU_LIST].removeNode(node) + } +} + +class Entry { + constructor (key, value, length, now, maxAge) { + this.key = key + this.value = value + this.length = length + this.now = now + this.maxAge = maxAge || 0 + } +} + +const forEachStep = (self, fn, node, thisp) => { + let hit = node.value + if (isStale(self, hit)) { + del(self, node) + if (!self[ALLOW_STALE]) + hit = undefined + } + if (hit) + fn.call(thisp, hit.value, hit.key, self) +} + +module.exports = LRUCache + +},{"yallist":3}],2:[function(require,module,exports){ +'use strict' +module.exports = function (Yallist) { + Yallist.prototype[Symbol.iterator] = function* () { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value + } + } +} + +},{}],3:[function(require,module,exports){ +'use strict' +module.exports = Yallist + +Yallist.Node = Node +Yallist.create = Yallist + +function Yallist (list) { + var self = this + if (!(self instanceof Yallist)) { + self = new Yallist() + } + + self.tail = null + self.head = null + self.length = 0 + + if (list && typeof list.forEach === 'function') { + list.forEach(function (item) { + self.push(item) + }) + } else if (arguments.length > 0) { + for (var i = 0, l = arguments.length; i < l; i++) { + self.push(arguments[i]) + } + } + + return self +} + +Yallist.prototype.removeNode = function (node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list') + } + + var next = node.next + var prev = node.prev + + if (next) { + next.prev = prev + } + + if (prev) { + prev.next = next + } + + if (node === this.head) { + this.head = next + } + if (node === this.tail) { + this.tail = prev + } + + node.list.length-- + node.next = null + node.prev = null + node.list = null +} + +Yallist.prototype.unshiftNode = function (node) { + if (node === this.head) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var head = this.head + node.list = this + node.next = head + if (head) { + head.prev = node + } + + this.head = node + if (!this.tail) { + this.tail = node + } + this.length++ +} + +Yallist.prototype.pushNode = function (node) { + if (node === this.tail) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var tail = this.tail + node.list = this + node.prev = tail + if (tail) { + tail.next = node + } + + this.tail = node + if (!this.head) { + this.head = node + } + this.length++ +} + +Yallist.prototype.push = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + push(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.unshift = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + unshift(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.pop = function () { + if (!this.tail) { + return undefined + } + + var res = this.tail.value + this.tail = this.tail.prev + if (this.tail) { + this.tail.next = null + } else { + this.head = null + } + this.length-- + return res +} + +Yallist.prototype.shift = function () { + if (!this.head) { + return undefined + } + + var res = this.head.value + this.head = this.head.next + if (this.head) { + this.head.prev = null + } else { + this.tail = null + } + this.length-- + return res +} + +Yallist.prototype.forEach = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.head, i = 0; walker !== null; i++) { + fn.call(thisp, walker.value, i, this) + walker = walker.next + } +} + +Yallist.prototype.forEachReverse = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { + fn.call(thisp, walker.value, i, this) + walker = walker.prev + } +} + +Yallist.prototype.get = function (n) { + for (var i = 0, walker = this.head; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.next + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.getReverse = function (n) { + for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.map = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.head; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.next + } + return res +} + +Yallist.prototype.mapReverse = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.tail; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.prev + } + return res +} + +Yallist.prototype.reduce = function (fn, initial) { + var acc + var walker = this.head + if (arguments.length > 1) { + acc = initial + } else if (this.head) { + walker = this.head.next + acc = this.head.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = 0; walker !== null; i++) { + acc = fn(acc, walker.value, i) + walker = walker.next + } + + return acc +} + +Yallist.prototype.reduceReverse = function (fn, initial) { + var acc + var walker = this.tail + if (arguments.length > 1) { + acc = initial + } else if (this.tail) { + walker = this.tail.prev + acc = this.tail.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = this.length - 1; walker !== null; i--) { + acc = fn(acc, walker.value, i) + walker = walker.prev + } + + return acc +} + +Yallist.prototype.toArray = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.head; walker !== null; i++) { + arr[i] = walker.value + walker = walker.next + } + return arr +} + +Yallist.prototype.toArrayReverse = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.tail; walker !== null; i++) { + arr[i] = walker.value + walker = walker.prev + } + return arr +} + +Yallist.prototype.slice = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = 0, walker = this.head; walker !== null && i < from; i++) { + walker = walker.next + } + for (; walker !== null && i < to; i++, walker = walker.next) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.sliceReverse = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { + walker = walker.prev + } + for (; walker !== null && i > from; i--, walker = walker.prev) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.reverse = function () { + var head = this.head + var tail = this.tail + for (var walker = head; walker !== null; walker = walker.prev) { + var p = walker.prev + walker.prev = walker.next + walker.next = p + } + this.head = tail + this.tail = head + return this +} + +function push (self, item) { + self.tail = new Node(item, self.tail, null, self) + if (!self.head) { + self.head = self.tail + } + self.length++ +} + +function unshift (self, item) { + self.head = new Node(item, null, self.head, self) + if (!self.tail) { + self.tail = self.head + } + self.length++ +} + +function Node (value, prev, next, list) { + if (!(this instanceof Node)) { + return new Node(value, prev, next, list) + } + + this.list = list + this.value = value + + if (prev) { + prev.next = this + this.prev = prev + } else { + this.prev = null + } + + if (next) { + next.prev = this + this.next = next + } else { + this.next = null + } +} + +try { + // add if support for Symbol.iterator is present + require('./iterator.js')(Yallist) +} catch (er) {} + +},{"./iterator.js":2}],4:[function(require,module,exports){ "use strict"; var gapi = _interopRequireWildcard(require("./gapi")); @@ -31,7 +755,7 @@ chrome.runtime.onConnect.addListener(function (port) { }); } else if (msg.type == 4) { calData[msg.data.id].getEvents(new Date(msg.data.start), new Date(msg.data.end)).catch(function (e) { - console.log("cannot load calendar ".concat(msg.data.id)); + console.log("cannot load calendar ".concat(msg.data.id), e); return []; }).then(function (data) { console.log(data); @@ -66,7 +790,7 @@ chrome.browserAction.onClicked.addListener(function () { }); }); -},{"./gapi":2}],2:[function(require,module,exports){ +},{"./gapi":5}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -77,6 +801,10 @@ exports.getCalendars = getCalendars; exports.getColors = getColors; exports.GCalendar = void 0; +var _lruCache = _interopRequireDefault(require("lru-cache")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } @@ -99,7 +827,6 @@ function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -/* global chrome */ var gapi_base = 'https://www.googleapis.com/calendar/v3'; var GApiError = { invalidSyncToken: 1, @@ -107,11 +834,17 @@ var GApiError = { }; function to_params(dict) { - return Object.entries(dict).map(function (_ref) { + return Object.entries(dict).filter(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), k = _ref2[0], v = _ref2[1]; + return v; + }).map(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + k = _ref4[0], + v = _ref4[1]; + return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v)); }).join('&'); } @@ -161,8 +894,11 @@ function getEvent(calId, eventId, token) { }); } -function getEvents(calId, token, syncToken) { - var resultsPerRequest = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 100; +function _getEvents(calId, token) { + var syncToken = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var timeMin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + var timeMax = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; + var resultsPerRequest = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 100; var results = []; var singleFetch = function singleFetch(pageToken, syncToken) { @@ -170,6 +906,8 @@ function getEvents(calId, token, syncToken) { access_token: token, pageToken: pageToken, syncToken: syncToken, + timeMin: timeMin, + timeMax: timeMax, maxResults: resultsPerRequest })), { method: 'GET', @@ -197,51 +935,116 @@ var GCalendar = /*#__PURE__*/ function () { function GCalendar(calId, name) { + var _this = this; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + maxCachedItems: 100, + nDaysPerSlot: 10, + largeQuery: 10 + }; + _classCallCheck(this, GCalendar); this.calId = calId; this.name = name; this.token = getAuthToken(); this.syncToken = ''; - this.cache = {}; + this.cache = new _lruCache.default({ + max: options.maxCachedItems, + dispose: function dispose(k, v) { + return _this.onRemoveSlot(k, v); + } + }); + this.eventMeta = {}; + this.options = options; + this.divider = 8.64e7 * this.options.nDaysPerSlot; } _createClass(GCalendar, [{ + key: "dateToCacheKey", + value: function dateToCacheKey(date) { + return Math.floor(date / this.divider); + } + }, { + key: "dateRangeToCacheKeys", + value: function dateRangeToCacheKeys(range) { + return { + start: this.dateToCacheKey(range.start), + end: this.dateToCacheKey(new Date(range.end.getTime() - 1)) + }; + } + }, { key: "getSlot", value: function getSlot(k) { - if (!this.cache[k]) this.cache[k] = {}; - return this.cache[k]; + if (!this.cache.has(k)) { + var res = {}; + this.cache.set(k, res); + return res; + } else return this.cache.get(k); + } + }, { + key: "onRemoveSlot", + value: function onRemoveSlot(k, v) { + for (var id in v) { + console.assert(this.eventMeta[id]); + var keys = this.eventMeta[id].keys; + keys.delete(k); + if (keys.size === 0) delete this.eventMeta[id]; + } + } + }, { + key: "slotStartDate", + value: function slotStartDate(k) { + return new Date(k * this.divider); + } + }, { + key: "slotEndDate", + value: function slotEndDate(k) { + return new Date((k + 1) * this.divider); } }, { key: "addEvent", value: function addEvent(e) { - var ks = GCalendar.dateToCacheKey(e.start); - var ke = GCalendar.dateToCacheKey(new Date(e.end.getTime() - 1)); + var evict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + //console.log('adding event', e); + if (this.eventMeta.hasOwnProperty(e.id)) this.removeEvent(e); + var r = this.dateRangeToCacheKeys(e); + var ks = r.start; + var ke = r.end; + var t = this.cache.length; + var keys = new Set(); + + for (var i = ks; i <= ke; i++) { + keys.add(i); + if (!this.cache.has(i)) t++; + } + + this.eventMeta[e.id] = { + keys: keys, + summary: e.summary + }; + if (!evict && t > this.options.maxCachedItems) return; if (ks === ke) this.getSlot(ks)[e.id] = { start: e.start, end: e.end, - id: e.id, - summary: e.summary + id: e.id };else { this.getSlot(ks)[e.id] = { start: e.start, - end: GCalendar.slotEndDate(ks), - id: e.id, - summary: e.summary + end: this.slotEndDate(ks), + id: e.id }; this.getSlot(ke)[e.id] = { - start: GCalendar.slotStartDate(ke), + start: this.slotStartDate(ke), end: e.end, - id: e.id, - summary: e.summary + id: e.id }; for (var k = ks + 1; k < ke; k++) { this.getSlot(k)[e.id] = { - start: GCalendar.slotStartDate(k), - end: GCalendar.slotEndDate(k), - id: e.id, - summary: e.summary + start: this.slotStartDate(k), + end: this.slotEndDate(k), + id: e.id }; } } @@ -249,17 +1052,20 @@ function () { }, { key: "removeEvent", value: function removeEvent(e) { - var ks = GCalendar.dateToCacheKey(e.start); - var ke = GCalendar.dateToCacheKey(new Date(e.end.getTime() - 1)); + var _this2 = this; - for (var k = ks; k <= ke; k++) { - delete this.getSlot(k)[e.id]; - } + var keys = this.eventMeta[e.id].keys; + console.assert(keys); + keys.forEach(function (k) { + return delete _this2.getSlot(k)[e.id]; + }); + delete this.eventMeta[e.id]; } }, { key: "getSlotEvents", value: function getSlotEvents(k, start, end) { - var s = this.getSlot(k); + var s = this.getSlot(k); //console.log(s); + var results = []; for (var id in s) { @@ -268,7 +1074,7 @@ function () { id: id, start: s[id].start < start ? start : s[id].start, end: s[id].end > end ? end : s[id].end, - summary: s[id].summary + summary: this.eventMeta[id].summary }); } } @@ -277,10 +1083,11 @@ function () { } }, { key: "getCachedEvents", - value: function getCachedEvents(start, end) { - var ks = GCalendar.dateToCacheKey(start); - var ke = GCalendar.dateToCacheKey(new Date(end.getTime() - 1)); - var results = this.getSlotEvents(ks, start, end); + value: function getCachedEvents(_r) { + var r = this.dateRangeToCacheKeys(_r); + var ks = r.start; + var ke = r.end; + var results = this.getSlotEvents(ks, _r.start, _r.end); for (var k = ks + 1; k < ke; k++) { var s = this.getSlot(k); @@ -290,59 +1097,115 @@ function () { } } - if (ke > ks) results.push.apply(results, _toConsumableArray(this.getSlotEvents(ke, start, end))); + if (ke > ks) results.push.apply(results, _toConsumableArray(this.getSlotEvents(ke, _r.start, _r.end))); return results; } }, { key: "sync", value: function sync() { - var _this = this; + var _this3 = this; return this.token.then(function (token) { - return getEvents(_this.calId, token, _this.syncToken).then(function (r) { - _this.syncToken = r.nextSyncToken; + return _getEvents(_this3.calId, token, _this3.syncToken).then(function (r) { + _this3.syncToken = r.nextSyncToken; var pm_results = r.results.map(function (e) { - return e.start ? Promise.resolve(e) : getEvent(_this.calId, e.id, token); + return e.start ? Promise.resolve(e) : getEvent(_this3.calId, e.id, token); }); return Promise.all(pm_results).then(function (results) { return results.forEach(function (e) { e.start = new Date(e.start.dateTime); e.end = new Date(e.end.dateTime); - if (e.status === 'confirmed') _this.addEvent(e);else if (e.status === 'cancelled') _this.removeEvent(e); + if (e.status === 'confirmed') _this3.addEvent(e);else if (e.status === 'cancelled') _this3.removeEvent(e); }); }); }); }).catch(function (e) { if (e === GApiError.invalidSyncToken) { - _this.syncToken = ''; + _this3.syncToken = ''; - _this.sync(); + _this3.sync(); } else throw e; }); } }, { key: "getEvents", value: function getEvents(start, end) { - var _this2 = this; + var _this4 = this; - return this.sync().then(function () { - return _this2.getCachedEvents(start, end); + var r = this.dateRangeToCacheKeys({ + start: start, + end: end }); - } - }], [{ - key: "dateToCacheKey", - value: function dateToCacheKey(date) { - return Math.floor(date / 8.64e7); - } - }, { - key: "slotStartDate", - value: function slotStartDate(k) { - return new Date(k * 8.64e7); - } - }, { - key: "slotEndDate", - value: function slotEndDate(k) { - return new Date((k + 1) * 8.64e7); + var query = {}; + + for (var k = r.start; k <= r.end; k++) { + if (!this.cache.has(k)) { + if (!query.hasOwnProperty('start')) query.start = k; + query.end = k; + } + } + + console.log("start: ".concat(start, " end: ").concat(end)); + + if (query.hasOwnProperty('start')) { + console.assert(query.start <= query.end); + + if (query.end - query.start + 1 > this.options.largeQuery) { + console.log("encounter large query, use direct fetch"); + return this.token.then(function (token) { + return _getEvents(_this4.calId, token, null, start.toISOString(), end.toISOString()).then(function (r) { + var results = []; + r.results.forEach(function (e) { + console.assert(e.start); + e.start = new Date(e.start.dateTime); + e.end = new Date(e.end.dateTime); + results.push(e); + }); + return results.filter(function (e) { + return !(e.start >= end || e.end <= start); + }).map(function (e) { + return { + id: e.id, + start: e.start < start ? start : e.start, + end: e.end > end ? end : e.end, + summary: e.summary + }; + }); + }); + }); + } + + console.log("fetching short event list"); + return this.token.then(function (token) { + return _getEvents(_this4.calId, token, null, _this4.slotStartDate(query.start).toISOString(), _this4.slotEndDate(query.end).toISOString()).then(function (r) { + if (_this4.syncToken === '') _this4.syncToken = r.nextSyncToken; + return r.results.forEach(function (e) { + if (e.status === 'confirmed') { + console.assert(e.start); + e.start = new Date(e.start.dateTime); + e.end = new Date(e.end.dateTime); + + _this4.addEvent(e, true); + } + }); + }); + }).then(function () { + return _this4.sync(); + }).then(function () { + return _this4.getCachedEvents({ + start: start, + end: end + }); + }); + } else { + console.log("cache hit"); + return this.sync().then(function () { + return _this4.getCachedEvents({ + start: start, + end: end + }); + }); + } } }]); @@ -351,5 +1214,5 @@ function () { exports.GCalendar = GCalendar; -},{}]},{},[1]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYmFja2dyb3VuZC5qcyIsInNyYy9nYXBpLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7QUNBQTs7OztBQUVBLElBQUksUUFBUSxHQUFHLEVBQWY7QUFDQSxJQUFJLFNBQVMsR0FBRyxFQUFoQjtBQUNBLElBQUksT0FBTyxHQUFHLEVBQWQ7QUFFQSxNQUFNLENBQUMsT0FBUCxDQUFlLFNBQWYsQ0FBeUIsV0FBekIsQ0FBcUMsVUFBUyxJQUFULEVBQWU7QUFDaEQsRUFBQSxPQUFPLENBQUMsTUFBUixDQUFlLElBQUksQ0FBQyxJQUFMLElBQWEsTUFBNUI7QUFDQSxFQUFBLElBQUksQ0FBQyxTQUFMLENBQWUsV0FBZixDQUEyQixVQUFTLEdBQVQsRUFBYztBQUNyQyxJQUFBLE9BQU8sQ0FBQyxHQUFSLENBQVksR0FBWjs7QUFDQSxRQUFJLEdBQUcsQ0FBQyxJQUFKLElBQVksQ0FBaEIsRUFBbUI7QUFDZixNQUFBLFFBQVEsR0FBRyxHQUFHLENBQUMsSUFBZjtBQUNILEtBRkQsTUFHSyxJQUFJLEdBQUcsQ0FBQyxJQUFKLElBQVksQ0FBaEIsRUFBbUI7QUFDcEIsTUFBQSxJQUFJLENBQUMsV0FBTCxDQUFpQjtBQUFFLFFBQUEsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFWO0FBQWMsUUFBQSxJQUFJLEVBQUUsQ0FBcEI7QUFBdUIsUUFBQSxJQUFJLEVBQUU7QUFBN0IsT0FBakI7QUFDSCxLQUZJLE1BR0EsSUFBSSxHQUFHLENBQUMsSUFBSixJQUFZLENBQWhCLEVBQW1CO0FBQ3BCLE1BQUEsU0FBUyxHQUFHLEdBQUcsQ0FBQyxJQUFoQjtBQUNILEtBRkksTUFHQSxJQUFJLEdBQUcsQ0FBQyxJQUFKLElBQVksQ0FBaEIsRUFBbUI7QUFDcEIsTUFBQSxJQUFJLENBQUMsV0FBTCxDQUFpQjtBQUFFLFFBQUEsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFWO0FBQWMsUUFBQSxJQUFJLEVBQUUsQ0FBcEI7QUFBdUIsUUFBQSxJQUFJLEVBQUU7QUFBN0IsT0FBakI7QUFDSCxLQUZJLE1BR0EsSUFBSSxHQUFHLENBQUMsSUFBSixJQUFZLENBQWhCLEVBQW1CO0FBQ3BCLE1BQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFKLENBQVMsRUFBVixDQUFQLENBQXFCLFNBQXJCLENBQStCLElBQUksSUFBSixDQUFTLEdBQUcsQ0FBQyxJQUFKLENBQVMsS0FBbEIsQ0FBL0IsRUFBeUQsSUFBSSxJQUFKLENBQVMsR0FBRyxDQUFDLElBQUosQ0FBUyxHQUFsQixDQUF6RCxFQUNLLEtBREwsQ0FDVyxVQUFBLENBQUMsRUFBSTtBQUNSLFFBQUEsT0FBTyxDQUFDLEdBQVIsZ0NBQW9DLEdBQUcsQ0FBQyxJQUFKLENBQVMsRUFBN0M7QUFDQSxlQUFPLEVBQVA7QUFDSCxPQUpMLEVBS0ssSUFMTCxDQUtVLFVBQUEsSUFBSSxFQUFJO0FBQ2QsUUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLElBQVo7QUFDQSxZQUFJLElBQUksR0FBRztBQUFFLFVBQUEsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFWO0FBQWMsVUFBQSxJQUFJLEVBQUUsQ0FBcEI7QUFBdUIsVUFBQSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUwsQ0FBUyxVQUFBLENBQUMsRUFBSTtBQUNsRCxtQkFBTztBQUNILGNBQUEsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQURIO0FBRUgsY0FBQSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUYsQ0FBUSxPQUFSLEVBRko7QUFHSCxjQUFBLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRixDQUFNLE9BQU47QUFIRixhQUFQO0FBS0gsV0FOdUM7QUFBN0IsU0FBWDtBQU9BLFFBQUEsT0FBTyxDQUFDLEdBQVIsQ0FBWSxJQUFaO0FBQ0EsUUFBQSxJQUFJLENBQUMsV0FBTCxDQUFpQixJQUFqQjtBQUNILE9BaEJEO0FBaUJILEtBbEJJLE1BbUJBLElBQUksR0FBRyxDQUFDLElBQUosSUFBWSxDQUFoQixFQUFtQjtBQUNwQixNQUFBLFNBQVMsR0FBRyxHQUFHLENBQUMsSUFBaEI7O0FBQ0EsV0FBSyxJQUFJLEVBQVQsSUFBZSxTQUFmLEVBQTBCO0FBQ3RCLFlBQUksQ0FBQyxPQUFPLENBQUMsY0FBUixDQUF1QixFQUF2QixDQUFMLEVBQ0ksT0FBTyxDQUFDLEVBQUQsQ0FBUCxHQUFjLElBQUksSUFBSSxDQUFDLFNBQVQsQ0FBbUIsRUFBbkIsRUFBdUIsU0FBUyxDQUFDLEVBQUQsQ0FBVCxDQUFjLE9BQXJDLENBQWQ7QUFDUDtBQUNKLEtBTkksTUFPQTtBQUNELE1BQUEsT0FBTyxDQUFDLEtBQVIsQ0FBYyxrQkFBZDtBQUNIO0FBQ0osR0EzQ0Q7QUE0Q0gsQ0E5Q0Q7QUFnREEsTUFBTSxDQUFDLGFBQVAsQ0FBcUIsU0FBckIsQ0FBK0IsV0FBL0IsQ0FBMkMsWUFBVztBQUNsRCxFQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksTUFBWixDQUFtQjtBQUFDLElBQUEsR0FBRyxFQUFFO0FBQU4sR0FBbkI7QUFDSCxDQUZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3REQTtBQUNBLElBQU0sU0FBUyxHQUFHLHdDQUFsQjtBQUVBLElBQU0sU0FBUyxHQUFHO0FBQ2QsRUFBQSxnQkFBZ0IsRUFBRSxDQURKO0FBRWQsRUFBQSxVQUFVLEVBQUU7QUFGRSxDQUFsQjs7QUFLQSxTQUFTLFNBQVQsQ0FBbUIsSUFBbkIsRUFBeUI7QUFDckIsU0FBTyxNQUFNLENBQUMsT0FBUCxDQUFlLElBQWYsRUFBcUIsR0FBckIsQ0FBeUI7QUFBQTtBQUFBLFFBQUUsQ0FBRjtBQUFBLFFBQUssQ0FBTDs7QUFBQSxxQkFBZSxrQkFBa0IsQ0FBQyxDQUFELENBQWpDLGNBQXdDLGtCQUFrQixDQUFDLENBQUQsQ0FBMUQ7QUFBQSxHQUF6QixFQUEwRixJQUExRixDQUErRixHQUEvRixDQUFQO0FBQ0g7O0FBRU0sU0FBUyxZQUFULEdBQXdCO0FBQzNCLFNBQU8sSUFBSSxPQUFKLENBQVksVUFBQSxRQUFRO0FBQUEsV0FDdkIsTUFBTSxDQUFDLFFBQVAsQ0FBZ0IsWUFBaEIsQ0FDSTtBQUFDLE1BQUEsV0FBVyxFQUFFO0FBQWQsS0FESixFQUN5QixVQUFBLEtBQUs7QUFBQSxhQUFJLFFBQVEsQ0FBQyxLQUFELENBQVo7QUFBQSxLQUQ5QixDQUR1QjtBQUFBLEdBQXBCLENBQVA7QUFHSDs7QUFFTSxTQUFTLFlBQVQsQ0FBc0IsS0FBdEIsRUFBNkI7QUFDaEMsU0FBTyxLQUFLLFdBQUksU0FBSixvQ0FBdUMsU0FBUyxDQUFDO0FBQUMsSUFBQSxZQUFZLEVBQUU7QUFBZixHQUFELENBQWhELEdBQ0o7QUFBRSxJQUFBLE1BQU0sRUFBRSxLQUFWO0FBQWlCLElBQUEsS0FBSyxFQUFFO0FBQXhCLEdBREksQ0FBTCxDQUVGLElBRkUsQ0FFRyxVQUFBLFFBQVE7QUFBQSxXQUFJLFFBQVEsQ0FBQyxJQUFULEVBQUo7QUFBQSxHQUZYLEVBR0YsSUFIRSxDQUdHLFVBQUEsSUFBSTtBQUFBLFdBQUksSUFBSSxDQUFDLEtBQVQ7QUFBQSxHQUhQLENBQVA7QUFJSDs7QUFFTSxTQUFTLFNBQVQsQ0FBbUIsS0FBbkIsRUFBMEI7QUFDN0IsU0FBTyxLQUFLLFdBQUksU0FBSixxQkFBd0IsU0FBUyxDQUFDO0FBQUMsSUFBQSxZQUFZLEVBQUU7QUFBZixHQUFELENBQWpDLEdBQ1I7QUFBRSxJQUFBLE1BQU0sRUFBRSxLQUFWO0FBQWlCLElBQUEsS0FBSyxFQUFFO0FBQXhCLEdBRFEsQ0FBTCxDQUVGLElBRkUsQ0FFRyxVQUFBLFFBQVE7QUFBQSxXQUFJLFFBQVEsQ0FBQyxJQUFULEVBQUo7QUFBQSxHQUZYLENBQVA7QUFHSDs7QUFFRCxTQUFTLFFBQVQsQ0FBa0IsS0FBbEIsRUFBeUIsT0FBekIsRUFBa0MsS0FBbEMsRUFBeUM7QUFDckMsU0FBTyxLQUFLLFdBQUksU0FBSix3QkFBMkIsS0FBM0IscUJBQTJDLE9BQTNDLGNBQXNELFNBQVMsQ0FBQztBQUFDLElBQUEsWUFBWSxFQUFFO0FBQWYsR0FBRCxDQUEvRCxHQUNSO0FBQUUsSUFBQSxNQUFNLEVBQUUsS0FBVjtBQUFpQixJQUFBLEtBQUssRUFBRTtBQUF4QixHQURRLENBQUwsQ0FFRixJQUZFLENBRUcsVUFBQSxRQUFRO0FBQUEsV0FBSSxRQUFRLENBQUMsSUFBVCxFQUFKO0FBQUEsR0FGWCxDQUFQO0FBR0g7O0FBRUQsU0FBUyxTQUFULENBQW1CLEtBQW5CLEVBQTBCLEtBQTFCLEVBQWlDLFNBQWpDLEVBQW1FO0FBQUEsTUFBdkIsaUJBQXVCLHVFQUFMLEdBQUs7QUFDL0QsTUFBSSxPQUFPLEdBQUcsRUFBZDs7QUFDQSxNQUFNLFdBQVcsR0FBRyxTQUFkLFdBQWMsQ0FBQyxTQUFELEVBQVksU0FBWjtBQUFBLFdBQTBCLEtBQUssV0FBSSxTQUFKLHdCQUEyQixLQUEzQixxQkFBMkMsU0FBUyxDQUFDO0FBQ2hHLE1BQUEsWUFBWSxFQUFFLEtBRGtGO0FBRWhHLE1BQUEsU0FBUyxFQUFULFNBRmdHO0FBR2hHLE1BQUEsU0FBUyxFQUFULFNBSGdHO0FBSWhHLE1BQUEsVUFBVSxFQUFFO0FBSm9GLEtBQUQsQ0FBcEQsR0FLekM7QUFBRSxNQUFBLE1BQU0sRUFBRSxLQUFWO0FBQWlCLE1BQUEsS0FBSyxFQUFFO0FBQXhCLEtBTHlDLENBQUwsQ0FNckMsSUFOcUMsQ0FNaEMsVUFBQSxRQUFRLEVBQUk7QUFDZCxVQUFJLFFBQVEsQ0FBQyxNQUFULEtBQW9CLEdBQXhCLEVBQ0ksT0FBTyxRQUFRLENBQUMsSUFBVCxFQUFQLENBREosS0FFSyxJQUFJLFFBQVEsQ0FBQyxNQUFULEtBQW9CLEdBQXhCLEVBQ0QsTUFBTSxTQUFTLENBQUMsZ0JBQWhCLENBREMsS0FFQSxNQUFNLFNBQVMsQ0FBQyxXQUFoQjtBQUNSLEtBWnFDLEVBYXJDLElBYnFDLENBYWhDLFVBQUEsSUFBSSxFQUFJO0FBQ1YsTUFBQSxPQUFPLENBQUMsSUFBUixPQUFBLE9BQU8scUJBQVMsSUFBSSxDQUFDLEtBQWQsRUFBUDs7QUFDQSxVQUFJLElBQUksQ0FBQyxhQUFULEVBQXdCO0FBQ3BCLGVBQU8sV0FBVyxDQUFDLElBQUksQ0FBQyxhQUFOLEVBQXFCLEVBQXJCLENBQWxCO0FBQ0gsT0FGRCxNQUVPO0FBQ0gsZUFBUTtBQUNKLFVBQUEsYUFBYSxFQUFFLElBQUksQ0FBQyxhQURoQjtBQUVKLFVBQUEsT0FBTyxFQUFQO0FBRkksU0FBUjtBQUlIO0FBQ0osS0F2QnFDLENBQTFCO0FBQUEsR0FBcEI7O0FBeUJBLFNBQU8sV0FBVyxDQUFDLEVBQUQsRUFBSyxTQUFMLENBQWxCO0FBQ0g7O0lBRVksUzs7O0FBQ1QscUJBQVksS0FBWixFQUFtQixJQUFuQixFQUF5QjtBQUFBOztBQUNyQixTQUFLLEtBQUwsR0FBYSxLQUFiO0FBQ0EsU0FBSyxJQUFMLEdBQVksSUFBWjtBQUNBLFNBQUssS0FBTCxHQUFhLFlBQVksRUFBekI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxTQUFLLEtBQUwsR0FBYSxFQUFiO0FBQ0g7Ozs7NEJBTU8sQyxFQUFHO0FBQ1AsVUFBSSxDQUFDLEtBQUssS0FBTCxDQUFXLENBQVgsQ0FBTCxFQUNJLEtBQUssS0FBTCxDQUFXLENBQVgsSUFBZ0IsRUFBaEI7QUFDSixhQUFPLEtBQUssS0FBTCxDQUFXLENBQVgsQ0FBUDtBQUNIOzs7NkJBS1EsQyxFQUFHO0FBQ1IsVUFBSSxFQUFFLEdBQUcsU0FBUyxDQUFDLGNBQVYsQ0FBeUIsQ0FBQyxDQUFDLEtBQTNCLENBQVQ7QUFDQSxVQUFJLEVBQUUsR0FBRyxTQUFTLENBQUMsY0FBVixDQUF5QixJQUFJLElBQUosQ0FBUyxDQUFDLENBQUMsR0FBRixDQUFNLE9BQU4sS0FBa0IsQ0FBM0IsQ0FBekIsQ0FBVDtBQUNBLFVBQUksRUFBRSxLQUFLLEVBQVgsRUFDSSxLQUFLLE9BQUwsQ0FBYSxFQUFiLEVBQWlCLENBQUMsQ0FBQyxFQUFuQixJQUF5QjtBQUNyQixRQUFBLEtBQUssRUFBRSxDQUFDLENBQUMsS0FEWTtBQUVyQixRQUFBLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FGYztBQUdyQixRQUFBLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFIZTtBQUlyQixRQUFBLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFKVSxPQUF6QixDQURKLEtBT0E7QUFDSSxhQUFLLE9BQUwsQ0FBYSxFQUFiLEVBQWlCLENBQUMsQ0FBQyxFQUFuQixJQUF5QjtBQUNyQixVQUFBLEtBQUssRUFBRSxDQUFDLENBQUMsS0FEWTtBQUVyQixVQUFBLEdBQUcsRUFBRSxTQUFTLENBQUMsV0FBVixDQUFzQixFQUF0QixDQUZnQjtBQUdyQixVQUFBLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFIZTtBQUlyQixVQUFBLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFKVSxTQUF6QjtBQUtBLGFBQUssT0FBTCxDQUFhLEVBQWIsRUFBaUIsQ0FBQyxDQUFDLEVBQW5CLElBQXlCO0FBQ3JCLFVBQUEsS0FBSyxFQUFFLFNBQVMsQ0FBQyxhQUFWLENBQXdCLEVBQXhCLENBRGM7QUFFckIsVUFBQSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBRmM7QUFHckIsVUFBQSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBSGU7QUFJckIsVUFBQSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBSlUsU0FBekI7O0FBS0EsYUFBSyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBbEIsRUFBcUIsQ0FBQyxHQUFHLEVBQXpCLEVBQTZCLENBQUMsRUFBOUI7QUFDSSxlQUFLLE9BQUwsQ0FBYSxDQUFiLEVBQWdCLENBQUMsQ0FBQyxFQUFsQixJQUF3QjtBQUNwQixZQUFBLEtBQUssRUFBRSxTQUFTLENBQUMsYUFBVixDQUF3QixDQUF4QixDQURhO0FBRXBCLFlBQUEsR0FBRyxFQUFFLFNBQVMsQ0FBQyxXQUFWLENBQXNCLENBQXRCLENBRmU7QUFHcEIsWUFBQSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBSGM7QUFJcEIsWUFBQSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBSlMsV0FBeEI7QUFESjtBQU1IO0FBQ0o7OztnQ0FFVyxDLEVBQUc7QUFDWCxVQUFJLEVBQUUsR0FBRyxTQUFTLENBQUMsY0FBVixDQUF5QixDQUFDLENBQUMsS0FBM0IsQ0FBVDtBQUNBLFVBQUksRUFBRSxHQUFHLFNBQVMsQ0FBQyxjQUFWLENBQXlCLElBQUksSUFBSixDQUFTLENBQUMsQ0FBQyxHQUFGLENBQU0sT0FBTixLQUFrQixDQUEzQixDQUF6QixDQUFUOztBQUNBLFdBQUssSUFBSSxDQUFDLEdBQUcsRUFBYixFQUFpQixDQUFDLElBQUksRUFBdEIsRUFBMEIsQ0FBQyxFQUEzQjtBQUNJLGVBQU8sS0FBSyxPQUFMLENBQWEsQ0FBYixFQUFnQixDQUFDLENBQUMsRUFBbEIsQ0FBUDtBQURKO0FBRUg7OztrQ0FFYSxDLEVBQUcsSyxFQUFPLEcsRUFBSztBQUN6QixVQUFJLENBQUMsR0FBRyxLQUFLLE9BQUwsQ0FBYSxDQUFiLENBQVI7QUFDQSxVQUFJLE9BQU8sR0FBRyxFQUFkOztBQUNBLFdBQUssSUFBSSxFQUFULElBQWUsQ0FBZixFQUFrQjtBQUNkLFlBQUksRUFBRSxDQUFDLENBQUMsRUFBRCxDQUFELENBQU0sS0FBTixJQUFlLEdBQWYsSUFBc0IsQ0FBQyxDQUFDLEVBQUQsQ0FBRCxDQUFNLEdBQU4sSUFBYSxLQUFyQyxDQUFKLEVBQ0E7QUFDSSxVQUFBLE9BQU8sQ0FBQyxJQUFSLENBQWE7QUFDVCxZQUFBLEVBQUUsRUFBRixFQURTO0FBRVQsWUFBQSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUQsQ0FBRCxDQUFNLEtBQU4sR0FBYyxLQUFkLEdBQXNCLEtBQXRCLEdBQTZCLENBQUMsQ0FBQyxFQUFELENBQUQsQ0FBTSxLQUZqQztBQUdULFlBQUEsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFELENBQUQsQ0FBTSxHQUFOLEdBQVksR0FBWixHQUFrQixHQUFsQixHQUF1QixDQUFDLENBQUMsRUFBRCxDQUFELENBQU0sR0FIekI7QUFJVCxZQUFBLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRCxDQUFELENBQU07QUFKTixXQUFiO0FBTUg7QUFDSjs7QUFDRCxhQUFPLE9BQVA7QUFDSDs7O29DQUVlLEssRUFBTyxHLEVBQUs7QUFDeEIsVUFBSSxFQUFFLEdBQUcsU0FBUyxDQUFDLGNBQVYsQ0FBeUIsS0FBekIsQ0FBVDtBQUNBLFVBQUksRUFBRSxHQUFHLFNBQVMsQ0FBQyxjQUFWLENBQXlCLElBQUksSUFBSixDQUFTLEdBQUcsQ0FBQyxPQUFKLEtBQWdCLENBQXpCLENBQXpCLENBQVQ7QUFDQSxVQUFJLE9BQU8sR0FBRyxLQUFLLGFBQUwsQ0FBbUIsRUFBbkIsRUFBdUIsS0FBdkIsRUFBOEIsR0FBOUIsQ0FBZDs7QUFDQSxXQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFsQixFQUFxQixDQUFDLEdBQUcsRUFBekIsRUFBNkIsQ0FBQyxFQUE5QixFQUNBO0FBQ0ksWUFBSSxDQUFDLEdBQUcsS0FBSyxPQUFMLENBQWEsQ0FBYixDQUFSOztBQUNBLGFBQUssSUFBSSxFQUFULElBQWUsQ0FBZjtBQUNJLFVBQUEsT0FBTyxDQUFDLElBQVIsQ0FBYSxDQUFDLENBQUMsRUFBRCxDQUFkO0FBREo7QUFFSDs7QUFDRCxVQUFJLEVBQUUsR0FBRyxFQUFULEVBQ0ksT0FBTyxDQUFDLElBQVIsT0FBQSxPQUFPLHFCQUFTLEtBQUssYUFBTCxDQUFtQixFQUFuQixFQUF1QixLQUF2QixFQUE4QixHQUE5QixDQUFULEVBQVA7QUFDSixhQUFPLE9BQVA7QUFDSDs7OzJCQUVNO0FBQUE7O0FBQ0gsYUFBTyxLQUFLLEtBQUwsQ0FBVyxJQUFYLENBQWdCLFVBQUEsS0FBSztBQUFBLGVBQUksU0FBUyxDQUFDLEtBQUksQ0FBQyxLQUFOLEVBQWEsS0FBYixFQUFvQixLQUFJLENBQUMsU0FBekIsQ0FBVCxDQUE2QyxJQUE3QyxDQUFrRCxVQUFBLENBQUMsRUFBSTtBQUNuRixVQUFBLEtBQUksQ0FBQyxTQUFMLEdBQWlCLENBQUMsQ0FBQyxhQUFuQjtBQUNBLGNBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxPQUFGLENBQVUsR0FBVixDQUFjLFVBQUEsQ0FBQztBQUFBLG1CQUFJLENBQUMsQ0FBQyxLQUFGLEdBQVUsT0FBTyxDQUFDLE9BQVIsQ0FBZ0IsQ0FBaEIsQ0FBVixHQUErQixRQUFRLENBQUMsS0FBSSxDQUFDLEtBQU4sRUFBYSxDQUFDLENBQUMsRUFBZixFQUFtQixLQUFuQixDQUEzQztBQUFBLFdBQWYsQ0FBakI7QUFDQSxpQkFBTyxPQUFPLENBQUMsR0FBUixDQUFZLFVBQVosRUFBd0IsSUFBeEIsQ0FBNkIsVUFBQSxPQUFPO0FBQUEsbUJBQUksT0FBTyxDQUFDLE9BQVIsQ0FBZ0IsVUFBQSxDQUFDLEVBQUk7QUFDaEUsY0FBQSxDQUFDLENBQUMsS0FBRixHQUFVLElBQUksSUFBSixDQUFTLENBQUMsQ0FBQyxLQUFGLENBQVEsUUFBakIsQ0FBVjtBQUNBLGNBQUEsQ0FBQyxDQUFDLEdBQUYsR0FBUSxJQUFJLElBQUosQ0FBUyxDQUFDLENBQUMsR0FBRixDQUFNLFFBQWYsQ0FBUjtBQUNBLGtCQUFJLENBQUMsQ0FBQyxNQUFGLEtBQWEsV0FBakIsRUFDSSxLQUFJLENBQUMsUUFBTCxDQUFjLENBQWQsRUFESixLQUVLLElBQUksQ0FBQyxDQUFDLE1BQUYsS0FBYSxXQUFqQixFQUNELEtBQUksQ0FBQyxXQUFMLENBQWlCLENBQWpCO0FBQ1AsYUFQOEMsQ0FBSjtBQUFBLFdBQXBDLENBQVA7QUFRSCxTQVgrQixDQUFKO0FBQUEsT0FBckIsRUFXSCxLQVhHLENBV0csVUFBQSxDQUFDLEVBQUk7QUFDWCxZQUFJLENBQUMsS0FBSyxTQUFTLENBQUMsZ0JBQXBCLEVBQXNDO0FBQ2xDLFVBQUEsS0FBSSxDQUFDLFNBQUwsR0FBaUIsRUFBakI7O0FBQ0EsVUFBQSxLQUFJLENBQUMsSUFBTDtBQUNILFNBSEQsTUFHTyxNQUFNLENBQU47QUFDVixPQWhCTSxDQUFQO0FBaUJIOzs7OEJBRVMsSyxFQUFPLEcsRUFBSztBQUFBOztBQUNsQixhQUFPLEtBQUssSUFBTCxHQUFZLElBQVosQ0FBaUI7QUFBQSxlQUFNLE1BQUksQ0FBQyxlQUFMLENBQXFCLEtBQXJCLEVBQTRCLEdBQTVCLENBQU47QUFBQSxPQUFqQixDQUFQO0FBQ0g7OzttQ0F4R3FCLEksRUFBTTtBQUN4QixhQUFPLElBQUksQ0FBQyxLQUFMLENBQVcsSUFBSSxHQUFHLE1BQWxCLENBQVA7QUFDSDs7O2tDQVFvQixDLEVBQUc7QUFBRSxhQUFPLElBQUksSUFBSixDQUFTLENBQUMsR0FBRyxNQUFiLENBQVA7QUFBOEI7OztnQ0FDckMsQyxFQUFHO0FBQUUsYUFBTyxJQUFJLElBQUosQ0FBUyxDQUFDLENBQUMsR0FBRyxDQUFMLElBQVUsTUFBbkIsQ0FBUDtBQUFvQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsImltcG9ydCAqIGFzIGdhcGkgZnJvbSAnLi9nYXBpJztcblxubGV0IHBhdHRlcm5zID0gW107XG5sZXQgY2FsZW5kYXJzID0ge307XG5sZXQgY2FsRGF0YSA9IHt9O1xuXG5jaHJvbWUucnVudGltZS5vbkNvbm5lY3QuYWRkTGlzdGVuZXIoZnVuY3Rpb24ocG9ydCkge1xuICAgIGNvbnNvbGUuYXNzZXJ0KHBvcnQubmFtZSA9PSAnbWFpbicpO1xuICAgIHBvcnQub25NZXNzYWdlLmFkZExpc3RlbmVyKGZ1bmN0aW9uKG1zZykge1xuICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuICAgICAgICBpZiAobXNnLnR5cGUgPT0gMCkge1xuICAgICAgICAgICAgcGF0dGVybnMgPSBtc2cuZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtc2cudHlwZSA9PSAxKSB7XG4gICAgICAgICAgICBwb3J0LnBvc3RNZXNzYWdlKHsgaWQ6IG1zZy5pZCwgdHlwZTogMSwgZGF0YTogcGF0dGVybnMgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobXNnLnR5cGUgPT0gMikge1xuICAgICAgICAgICAgY2FsZW5kYXJzID0gbXNnLmRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobXNnLnR5cGUgPT0gMykge1xuICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7IGlkOiBtc2cuaWQsIHR5cGU6IDMsIGRhdGE6IGNhbGVuZGFycyB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtc2cudHlwZSA9PSA0KSB7XG4gICAgICAgICAgICBjYWxEYXRhW21zZy5kYXRhLmlkXS5nZXRFdmVudHMobmV3IERhdGUobXNnLmRhdGEuc3RhcnQpLCBuZXcgRGF0ZShtc2cuZGF0YS5lbmQpKVxuICAgICAgICAgICAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYGNhbm5vdCBsb2FkIGNhbGVuZGFyICR7bXNnLmRhdGEuaWR9YCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGRhdGEpO1xuICAgICAgICAgICAgICAgIGxldCByZXNwID0geyBpZDogbXNnLmlkLCB0eXBlOiA0LCBkYXRhOiBkYXRhLm1hcChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IGUuc3RhcnQuZ2V0VGltZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBlLmVuZC5nZXRUaW1lKClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pfTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwKTtcbiAgICAgICAgICAgICAgICBwb3J0LnBvc3RNZXNzYWdlKHJlc3ApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobXNnLnR5cGUgPT0gNSkge1xuICAgICAgICAgICAgY2FsZW5kYXJzID0gbXNnLmRhdGE7XG4gICAgICAgICAgICBmb3IgKGxldCBpZCBpbiBjYWxlbmRhcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhbERhdGEuaGFzT3duUHJvcGVydHkoaWQpKVxuICAgICAgICAgICAgICAgICAgICBjYWxEYXRhW2lkXSA9IG5ldyBnYXBpLkdDYWxlbmRhcihpZCwgY2FsZW5kYXJzW2lkXS5zdW1tYXJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJ1bmtub3duIG1zZyB0eXBlXCIpO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcblxuY2hyb21lLmJyb3dzZXJBY3Rpb24ub25DbGlja2VkLmFkZExpc3RlbmVyKGZ1bmN0aW9uKCkge1xuICAgIGNocm9tZS50YWJzLmNyZWF0ZSh7dXJsOiAnaW5kZXguaHRtbCd9KTtcbn0pO1xuXG4iLCIvKiBnbG9iYWwgY2hyb21lICovXG5jb25zdCBnYXBpX2Jhc2UgPSAnaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY2FsZW5kYXIvdjMnO1xuXG5jb25zdCBHQXBpRXJyb3IgPSB7XG4gICAgaW52YWxpZFN5bmNUb2tlbjogMSxcbiAgICBvdGhlckVycm9yOiAyLFxufTtcblxuZnVuY3Rpb24gdG9fcGFyYW1zKGRpY3QpIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZGljdCkubWFwKChbaywgdl0pID0+IGAke2VuY29kZVVSSUNvbXBvbmVudChrKX09JHtlbmNvZGVVUklDb21wb25lbnQodil9YCkuam9pbignJicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aFRva2VuKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlciA9PlxuICAgICAgICBjaHJvbWUuaWRlbnRpdHkuZ2V0QXV0aFRva2VuKFxuICAgICAgICAgICAge2ludGVyYWN0aXZlOiB0cnVlfSwgdG9rZW4gPT4gcmVzb2x2ZXIodG9rZW4pKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDYWxlbmRhcnModG9rZW4pIHtcbiAgICByZXR1cm4gZmV0Y2goYCR7Z2FwaV9iYXNlfS91c2Vycy9tZS9jYWxlbmRhckxpc3Q/JHt0b19wYXJhbXMoe2FjY2Vzc190b2tlbjogdG9rZW59KX1gLFxuICAgICAgICAgICAgeyBtZXRob2Q6ICdHRVQnLCBhc3luYzogdHJ1ZSB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS5qc29uKCkpXG4gICAgICAgIC50aGVuKGRhdGEgPT4gZGF0YS5pdGVtcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2xvcnModG9rZW4pIHtcbiAgICByZXR1cm4gZmV0Y2goYCR7Z2FwaV9iYXNlfS9jb2xvcnM/JHt0b19wYXJhbXMoe2FjY2Vzc190b2tlbjogdG9rZW59KX1gLFxuICAgICAgICB7IG1ldGhvZDogJ0dFVCcsIGFzeW5jOiB0cnVlIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmpzb24oKSk7XG59XG5cbmZ1bmN0aW9uIGdldEV2ZW50KGNhbElkLCBldmVudElkLCB0b2tlbikge1xuICAgIHJldHVybiBmZXRjaChgJHtnYXBpX2Jhc2V9L2NhbGVuZGFycy8ke2NhbElkfS9ldmVudHMvJHtldmVudElkfT8ke3RvX3BhcmFtcyh7YWNjZXNzX3Rva2VuOiB0b2tlbn0pfWAsXG4gICAgICAgIHsgbWV0aG9kOiAnR0VUJywgYXN5bmM6IHRydWUgfSlcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UuanNvbigpKTtcbn1cblxuZnVuY3Rpb24gZ2V0RXZlbnRzKGNhbElkLCB0b2tlbiwgc3luY1Rva2VuLCByZXN1bHRzUGVyUmVxdWVzdD0xMDApIHtcbiAgICBsZXQgcmVzdWx0cyA9IFtdO1xuICAgIGNvbnN0IHNpbmdsZUZldGNoID0gKHBhZ2VUb2tlbiwgc3luY1Rva2VuKSA9PiBmZXRjaChgJHtnYXBpX2Jhc2V9L2NhbGVuZGFycy8ke2NhbElkfS9ldmVudHM/JHt0b19wYXJhbXMoe1xuICAgICAgICAgICAgYWNjZXNzX3Rva2VuOiB0b2tlbixcbiAgICAgICAgICAgIHBhZ2VUb2tlbixcbiAgICAgICAgICAgIHN5bmNUb2tlbixcbiAgICAgICAgICAgIG1heFJlc3VsdHM6IHJlc3VsdHNQZXJSZXF1ZXN0XG4gICAgICAgIH0pfWAsIHsgbWV0aG9kOiAnR0VUJywgYXN5bmM6IHRydWUgfSlcbiAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAyMDApXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MTApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IEdBcGlFcnJvci5pbnZhbGlkU3luY1Rva2VuO1xuICAgICAgICAgICAgICAgIGVsc2UgdGhyb3cgR0FwaUVycm9yLm90aGVyRXJyb3JzO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCguLi5kYXRhLml0ZW1zKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5uZXh0UGFnZVRva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzaW5nbGVGZXRjaChkYXRhLm5leHRQYWdlVG9rZW4sICcnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTeW5jVG9rZW46IGRhdGEubmV4dFN5bmNUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgIHJldHVybiBzaW5nbGVGZXRjaCgnJywgc3luY1Rva2VuKTtcbn1cblxuZXhwb3J0IGNsYXNzIEdDYWxlbmRhciB7XG4gICAgY29uc3RydWN0b3IoY2FsSWQsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5jYWxJZCA9IGNhbElkO1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLnRva2VuID0gZ2V0QXV0aFRva2VuKCk7XG4gICAgICAgIHRoaXMuc3luY1Rva2VuID0gJyc7XG4gICAgICAgIHRoaXMuY2FjaGUgPSB7fTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZGF0ZVRvQ2FjaGVLZXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihkYXRlIC8gOC42NGU3KTtcbiAgICB9XG5cbiAgICBnZXRTbG90KGspIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhY2hlW2tdKVxuICAgICAgICAgICAgdGhpcy5jYWNoZVtrXSA9IHt9O1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVtrXTtcbiAgICB9XG5cbiAgICBzdGF0aWMgc2xvdFN0YXJ0RGF0ZShrKSB7IHJldHVybiBuZXcgRGF0ZShrICogOC42NGU3KTsgfVxuICAgIHN0YXRpYyBzbG90RW5kRGF0ZShrKSB7IHJldHVybiBuZXcgRGF0ZSgoayArIDEpICogOC42NGU3KTsgfVxuXG4gICAgYWRkRXZlbnQoZSkge1xuICAgICAgICBsZXQga3MgPSBHQ2FsZW5kYXIuZGF0ZVRvQ2FjaGVLZXkoZS5zdGFydCk7XG4gICAgICAgIGxldCBrZSA9IEdDYWxlbmRhci5kYXRlVG9DYWNoZUtleShuZXcgRGF0ZShlLmVuZC5nZXRUaW1lKCkgLSAxKSk7XG4gICAgICAgIGlmIChrcyA9PT0ga2UpXG4gICAgICAgICAgICB0aGlzLmdldFNsb3Qoa3MpW2UuaWRdID0ge1xuICAgICAgICAgICAgICAgIHN0YXJ0OiBlLnN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZDogZS5lbmQsXG4gICAgICAgICAgICAgICAgaWQ6IGUuaWQsXG4gICAgICAgICAgICAgICAgc3VtbWFyeTogZS5zdW1tYXJ5fTtcbiAgICAgICAgZWxzZVxuICAgICAgICB7XG4gICAgICAgICAgICB0aGlzLmdldFNsb3Qoa3MpW2UuaWRdID0ge1xuICAgICAgICAgICAgICAgIHN0YXJ0OiBlLnN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZDogR0NhbGVuZGFyLnNsb3RFbmREYXRlKGtzKSxcbiAgICAgICAgICAgICAgICBpZDogZS5pZCxcbiAgICAgICAgICAgICAgICBzdW1tYXJ5OiBlLnN1bW1hcnl9O1xuICAgICAgICAgICAgdGhpcy5nZXRTbG90KGtlKVtlLmlkXSA9IHtcbiAgICAgICAgICAgICAgICBzdGFydDogR0NhbGVuZGFyLnNsb3RTdGFydERhdGUoa2UpLFxuICAgICAgICAgICAgICAgIGVuZDogZS5lbmQsXG4gICAgICAgICAgICAgICAgaWQ6IGUuaWQsXG4gICAgICAgICAgICAgICAgc3VtbWFyeTogZS5zdW1tYXJ5fTtcbiAgICAgICAgICAgIGZvciAobGV0IGsgPSBrcyArIDE7IGsgPCBrZTsgaysrKVxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0U2xvdChrKVtlLmlkXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IEdDYWxlbmRhci5zbG90U3RhcnREYXRlKGspLFxuICAgICAgICAgICAgICAgICAgICBlbmQ6IEdDYWxlbmRhci5zbG90RW5kRGF0ZShrKSxcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGUuaWQsXG4gICAgICAgICAgICAgICAgICAgIHN1bW1hcnk6IGUuc3VtbWFyeX07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVFdmVudChlKSB7XG4gICAgICAgIGxldCBrcyA9IEdDYWxlbmRhci5kYXRlVG9DYWNoZUtleShlLnN0YXJ0KTtcbiAgICAgICAgbGV0IGtlID0gR0NhbGVuZGFyLmRhdGVUb0NhY2hlS2V5KG5ldyBEYXRlKGUuZW5kLmdldFRpbWUoKSAtIDEpKTtcbiAgICAgICAgZm9yIChsZXQgayA9IGtzOyBrIDw9IGtlOyBrKyspXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5nZXRTbG90KGspW2UuaWRdO1xuICAgIH1cblxuICAgIGdldFNsb3RFdmVudHMoaywgc3RhcnQsIGVuZCkge1xuICAgICAgICBsZXQgcyA9IHRoaXMuZ2V0U2xvdChrKTtcbiAgICAgICAgbGV0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaWQgaW4gcykge1xuICAgICAgICAgICAgaWYgKCEoc1tpZF0uc3RhcnQgPj0gZW5kIHx8IHNbaWRdLmVuZCA8PSBzdGFydCkpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzW2lkXS5zdGFydCA8IHN0YXJ0ID8gc3RhcnQ6IHNbaWRdLnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBlbmQ6IHNbaWRdLmVuZCA+IGVuZCA/IGVuZDogc1tpZF0uZW5kLFxuICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5OiBzW2lkXS5zdW1tYXJ5XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfVxuXG4gICAgZ2V0Q2FjaGVkRXZlbnRzKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgbGV0IGtzID0gR0NhbGVuZGFyLmRhdGVUb0NhY2hlS2V5KHN0YXJ0KTtcbiAgICAgICAgbGV0IGtlID0gR0NhbGVuZGFyLmRhdGVUb0NhY2hlS2V5KG5ldyBEYXRlKGVuZC5nZXRUaW1lKCkgLSAxKSk7XG4gICAgICAgIGxldCByZXN1bHRzID0gdGhpcy5nZXRTbG90RXZlbnRzKGtzLCBzdGFydCwgZW5kKTtcbiAgICAgICAgZm9yIChsZXQgayA9IGtzICsgMTsgayA8IGtlOyBrKyspXG4gICAgICAgIHtcbiAgICAgICAgICAgIGxldCBzID0gdGhpcy5nZXRTbG90KGspO1xuICAgICAgICAgICAgZm9yIChsZXQgaWQgaW4gcylcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goc1tpZF0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChrZSA+IGtzKVxuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKC4uLnRoaXMuZ2V0U2xvdEV2ZW50cyhrZSwgc3RhcnQsIGVuZCkpO1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9XG5cbiAgICBzeW5jKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlbi50aGVuKHRva2VuID0+IGdldEV2ZW50cyh0aGlzLmNhbElkLCB0b2tlbiwgdGhpcy5zeW5jVG9rZW4pLnRoZW4ociA9PiB7XG4gICAgICAgICAgICB0aGlzLnN5bmNUb2tlbiA9IHIubmV4dFN5bmNUb2tlbjtcbiAgICAgICAgICAgIGxldCBwbV9yZXN1bHRzID0gci5yZXN1bHRzLm1hcChlID0+IGUuc3RhcnQgPyBQcm9taXNlLnJlc29sdmUoZSkgOiBnZXRFdmVudCh0aGlzLmNhbElkLCBlLmlkLCB0b2tlbikpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHBtX3Jlc3VsdHMpLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzLmZvckVhY2goZSA9PiB7XG4gICAgICAgICAgICAgICAgZS5zdGFydCA9IG5ldyBEYXRlKGUuc3RhcnQuZGF0ZVRpbWUpO1xuICAgICAgICAgICAgICAgIGUuZW5kID0gbmV3IERhdGUoZS5lbmQuZGF0ZVRpbWUpO1xuICAgICAgICAgICAgICAgIGlmIChlLnN0YXR1cyA9PT0gJ2NvbmZpcm1lZCcpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkRXZlbnQoZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZS5zdGF0dXMgPT09ICdjYW5jZWxsZWQnKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50KGUpO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICBpZiAoZSA9PT0gR0FwaUVycm9yLmludmFsaWRTeW5jVG9rZW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNUb2tlbiA9ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMuc3luYygpO1xuICAgICAgICAgICAgfSBlbHNlIHRocm93IGU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldEV2ZW50cyhzdGFydCwgZW5kKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmMoKS50aGVuKCgpID0+IHRoaXMuZ2V0Q2FjaGVkRXZlbnRzKHN0YXJ0LCBlbmQpKTtcbiAgICB9XG59XG4iXX0= +},{"lru-cache":1}]},{},[4]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvbHJ1LWNhY2hlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3lhbGxpc3QvaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMveWFsbGlzdC95YWxsaXN0LmpzIiwic3JjL2JhY2tncm91bmQuanMiLCJzcmMvZ2FwaS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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